简体   繁体   中英

Export beans through HttpInvoker based on beans of certain interface

We have beans implementing a interface, lets say MyServicesInterface which we can autowire in java as a list using

@Autowired List{MyServicesInterface} myServices;

I would like to do this in a application context using sudo code like below.

<beans>

  <util:list id="servicesList" class="ArrayList" autowire-interface="com.MyServicesInterface" />
  <for-each service:services>
      <bean id="{/remote + service.getname}" class="org....HttpInvoker">
          <property name="serviceInterface" class="{#service.getInterface()}"
      </bean>
  </for-each>

<beans>

This kind of dynamic for-each bean of type {Interface} create a exporter bean would be a great pattern for exporting beans. I know this can be done in java but having some difficulties create a HttpInvoker in java for each beans. I doubt this can be done completely in a application context but perhaps there is a approach i am overlooking.

Any comments or suggests would be great.

Use a BeanDefinitionRegistryPostProcessor to create the BeanDefinitions for your HttpInvokerServiceExporters. Use an annotation to mark the services and define the interface you want to export.

eg

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    for (String name : registry.getBeanDefinitionNames()) {
        try {
            BeanDefinition definition = registry.getBeanDefinition(name);
            String beanClassName = defintition.getBeanClassName();

            cls = classLoader.loadClass(beanClassName);

            if(cls.isAnnotationPresent(ExportableService.class)){
                //Get annotation and pull out serviceInterface
                GenericBeanDefinition beanDef = new GenericBeanDefinition();
                beanDef.setBeanClass(HttpInvokerServiceExporter.class);

                MutablePropertyValues values = new MutablePropertyValues();
                values.addPropertyValue("service", new RuntimeBeanReference(name));
                values.addPropertyValue("serviceInterface", "service interface from annotation>);

                beanDef.setPropertyValues(values);

                // Bean name here should be e.g. /myService so its picked up by the BeanNameUrlHandlerMapping (if you so desire)
                registry.registerBeanDefinition(<beanName>, beanDef);
            }
        }
    } catch(ClassNotFoundException e){
        // Handle exception
    }
}

I doubt U can do it with xml context, but With java it is simple. So In java I would do like that:

List<MyServicesInterface> mylist =  applicationContext.getBeansOfType(MyServicesInterface.class).values();

ServiceInterface si = applicationContext.getBean(ServiceInterface.class);
for(MyServicesInterface mi: mylist){
    si.callSomething(mi);
}

That how I would it in java.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM