首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >FactoryBeans和Spring3.0中基于注释的配置

FactoryBeans和Spring3.0中基于注释的配置
EN

Stack Overflow用户
提问于 2011-04-04 23:57:12
回答 6查看 46.8K关注 0票数 24

Spring提供了FactoryBean接口,允许对beans进行非平凡的初始化。该框架提供了许多工厂bean的实现,并且--当使用Spring的XML配置时--工厂bean很容易使用。

然而,在Spring3.0中,我找不到一种令人满意的方法来将工厂bean与基于注释的配置(née JavaConfig)一起使用。

显然,我可以手动实例化工厂bean并自己设置任何所需的属性,如下所示:

代码语言:javascript
运行
复制
@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的回调接口,比如InitializingBeanApplicationContextAwareBeanClassLoaderAware@PostConstruct,那么这将会失败。我还需要检查FactoryBean,找出它实现了什么回调接口,然后通过调用setApplicationContextafterPropertiesSet()等实现这个功能。

对我来说,这感觉很笨拙,而且前后颠倒:应用程序开发人员不应该实现IOC容器的回调。

有没有人知道从Spring Annotation配置中使用FactoryBeans的更好的解决方案?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-04-05 00:55:47

据我所知,您的问题是您希望sqlSessionFactory()的结果是一个SqlSessionFactory (用于其他方法),但您必须从Spring方法返回SqlSessionFactoryBean才能触发@Bean回调。

可以通过以下解决方法解决此问题:

代码语言:javascript
运行
复制
@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

票数 21
EN

Stack Overflow用户

发布于 2012-01-26 17:42:00

我认为当你依靠自动布线时,这是最好的解决方案。如果您对bean使用Java配置,则如下所示:

代码语言:javascript
运行
复制
@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,这也应该是可行的。

票数 22
EN

Stack Overflow用户

发布于 2012-02-21 07:19:33

Spring有一个ConfigurationSupport类,该类有一个与JavaConfig一起使用的getObject()方法。

你会用它来扩展

代码语言:javascript
运行
复制
@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的示例

代码语言:javascript
运行
复制
@Configuration
public class DataConfig {
    @Bean
    public SessionFactory sessionFactory() {
        return new SessionFactoryBean()
           .setDataSource(dataSource())
           .setMappingLocations("classpath:com/myco/*.hbm.xml"})
           .buildSessionFactory();
    }
}

一些背景here

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5541094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档