Spring BeanFactoryPostProcessor problem
I want to create a Spring BeanFactoryPostProcessor that add beans to the current ApplicationContext.
I have a lot of Web-Services definition in my spring-ws-config.xml
and I want to reduce as much as possible.
XML Configuration
The configuration looks like:
<bean id="menu"
class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition"
lazy-init="true">
<property name="schemaCollection">
<bean
class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="inline" value="true" />
<property name="xsds">
<list>
<value>classpath:xsd.xsd</value>
</list>
</property>
</bean>
</property>
<property name="portTypeName" value="portType" />
<property name="serviceName" value="serviceName" />
<property name="locationUri" value="/endpoints" />
</bean>
Java Configuration
So, I create a @Configuration class with the following bean definition:
@Bean
@Lazy
public DefaultWsdl11Definition webService() throws IOException {
logger.info("Creating Web Service");
DefaultWsdl11Definition toRet = new DefaultWsdl11Definition();
toRet.setPortTypeName("portType");
toRet.setServiceName("serviceName");
CommonsXsdSchemaCollection collection = new CommonsXsdSchemaCollection();
collection.setInline(true);
collection.setXsds(new Resource[] { new ClassPathResource("path1") });
collection.afterPropertiesSet();
toRet.setSchemaCollection(collection);
toRet.setLocationUri("/endpoints");
return toRet;
}
This is much better!, but I want to reduce it more, so I want to create a annotation called @WebServiceDefinition, and add a BeanFactoryPostProcessor to create the beans automatically, so I wrote this:
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf)
throws BeansException {
Map<String, Object> beans = bf.getBeansWithAnnotation(WebService.class);
for (Entry<String, Object> entry : beans.entrySet()) {
Object bean = entry.getValue();
WebService ws = bean.getClass().getAnnotation(WebService.class);
String name = getName(entry.getKey());
DefaultWsdl11Definition newWS = createWebService(name, ws.xsds());
bf.registerSingleton(name, newWS);
}
}
But, this doesn't works!, I wrote a simple test, you can see it here
I see that the IOC don't work with the classes with the annotations, this is because the method: BeanFactory#getBeansWithAnnotation don't initialize it, mark it as created, and dont inject anything.
Workaround
I do a workaround: get all beans by name, get the corresponde class and use #bf.getBeansOfType(Class), (this method dont initialize it!).
My questions:
- This is a valid workaround?
- How I can use the method #getBeansWithAnnotation() and don't initialize the bean?