Spring提供了FactoryBean
接口,允许对beans进行非平凡的初始化。该框架提供了许多工厂bean的实现,并且--当使用Spring的XML配置时--工厂bean很容易使用。
然而,在Spring3.0中,我找不到一种令人满意的方法来将工厂bean与基于注释的配置(née JavaConfig)一起使用。
显然,我可以手动实例化工厂bean并自己设置任何所需的属性,如下所示:
@Configuration
public class AppConfig {
...
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource());
factory.setAnotherProperty(anotherProperty());
return factory.getObject();
}
然而,如果FactoryBean
实现了任何特定于Spring的回调接口,比如InitializingBean
、ApplicationContextAware
、BeanClassLoaderAware
或@PostConstruct
,那么这将会失败。我还需要检查FactoryBean,找出它实现了什么回调接口,然后通过调用setApplicationContext
、afterPropertiesSet()
等实现这个功能。
对我来说,这感觉很笨拙,而且前后颠倒:应用程序开发人员不应该实现IOC容器的回调。
有没有人知道从Spring Annotation配置中使用FactoryBeans的更好的解决方案?
发布于 2011-04-05 00:55:47
据我所知,您的问题是您希望sqlSessionFactory()
的结果是一个SqlSessionFactory
(用于其他方法),但您必须从Spring方法返回SqlSessionFactoryBean
才能触发@Bean
回调。
可以通过以下解决方法解决此问题:
@Configuration
public class AppConfig {
@Bean(name = "sqlSessionFactory")
public SqlSessionFactoryBean sqlSessionFactoryBean() { ... }
// FactoryBean is hidden behind this method
public SqlSessionFactory sqlSessionFactory() {
try {
return sqlSessionFactoryBean().getObject();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
@Bean
public AnotherBean anotherBean() {
return new AnotherBean(sqlSessionFactory());
}
}
关键是,对@Bean
-annotated方法的调用被一个方面截获,该方面对返回的bean(在本例中为FactoryBean
)执行初始化,因此在sqlSessionFactory()
中对sqlSessionFactoryBean()
的调用将返回一个完全初始化的FactoryBean
。
发布于 2012-01-26 17:42:00
我认为当你依靠自动布线时,这是最好的解决方案。如果您对bean使用Java配置,则如下所示:
@Bean
MyFactoryBean myFactory()
{
// this is a spring FactoryBean for MyBean
// i.e. something that implements FactoryBean<MyBean>
return new MyFactoryBean();
}
@Bean
MyOtherBean myOther(final MyBean myBean)
{
return new MyOtherBean(myBean);
}
因此Spring将为我们注入由myFactory().getObject()返回的MyBean实例,就像它对XML配置所做的那样。
如果你在@Component/@Service等类中使用@Inject/@Autowire,这也应该是可行的。
发布于 2012-02-21 07:19:33
Spring有一个ConfigurationSupport类,该类有一个与JavaConfig一起使用的getObject()方法。
你会用它来扩展
@Configuration
public class MyConfig extends ConfigurationSupport {
@Bean
public MyBean getMyBean() {
MyFactoryBean factory = new MyFactoryBean();
return (MyBean) getObject(factory);
}
}
在这个jira issue中有一些背景知识
在Spring3.0中,JavaConfig被移到了Spring core中,并决定摆脱ConfigurationSupport类。建议的方法是现在使用构建器模式而不是工厂。
取自新的SessionFactoryBuilder的示例
@Configuration
public class DataConfig {
@Bean
public SessionFactory sessionFactory() {
return new SessionFactoryBean()
.setDataSource(dataSource())
.setMappingLocations("classpath:com/myco/*.hbm.xml"})
.buildSessionFactory();
}
}
一些背景here
https://stackoverflow.com/questions/5541094
复制相似问题