Spring provides the FactoryBean interface to allow non-trivial initialisation of beans. The framework provides many implementations of factory beans and — when using Spring’s XML config — factory beans are easy to use.
However, in Spring 3.0, I can’t find a satisfactory way of using factory beans with the annotation-based configuration (née JavaConfig).
Obviously, I could manually instantiate the factory bean and set any required properties myself, like so:
@Configuration
public class AppConfig {
...
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setAnotherProperty(anotherProperty());
return factory.getObject();
}
However, this would fail if the FactoryBean implemented any Spring-specific callback interfaces, like InitializingBean, ApplicationContextAware, BeanClassLoaderAware, or @PostConstruct for example. I also need to inspect the FactoryBean, find out what callback interfaces it implements, then implement this functionality myself by calling setApplicationContext, afterPropertiesSet() etc.
This feels awkward and back-to-front to me: application-developers should not have to implement the callbacks of the IOC container.
Does anyone know of a better solution to using FactoryBeans from Spring Annotation configs?
As far as I understand your problem is what you want a result of
sqlSessionFactory()to be aSqlSessionFactory(for use in other methods), but you have to returnSqlSessionFactoryBeanfrom a@Bean-annotated method in order to trigger Spring callbacks.It can be solved with the following workaround:
The point is that calls to
@Bean-annotated methods are intercepted by an aspect which performs initialization of the beans being returned (FactoryBeanin your case), so that call tosqlSessionFactoryBean()insqlSessionFactory()returns a fully initializedFactoryBean.