Spring FactoryBean用法

问题描述 投票:0回答:4

我有一个应用程序,我希望能够基于属性文件中的值切换DAO实现。 Spring FactoryBean接口看起来可以很好地工作,因为我可以通过FactoryBean提供DAO,在其中可以执行基于属性值的切换工作。

但是,this springsource博客文章的最后一段提到了这一警告:

这里重要的一点是,驻留在Spring容器中并享受生命周期挂钩和容器服务的是FactoryBean,而不是分解对象本身。返回的实例是瞬态的-Spring对您从getObject()返回的内容一无所知,并且不会尝试执行任何生命周期挂钩或其他任何操作。

我的DAO对象包含Spring批注@Repository@Transactional。根据以上段落,如果我通过FactoryBean返回DAO实现,这些注释将被忽略吗?如果是这样,什么是确保Spring管理由FactoryBean返回的bean的好方法?

编辑:似乎大多数人都为该问题提供了替代配置解决方案。尽管我愿意接受这些建议(如果好的建议会予以支持),但我的问题实际上与正确使用FactoryBean有关,我将根据这些问题标记正确的答案。

java spring
4个回答
2
投票

假设您有这样的东西:

public interface FooDao {
   // ...
}

@Repository("firstFooDao")
public class FirstFooDao  implements FooDao {
   //...
}

@Repository("secondFooDao")
public class SecondFooDao  implements FooDao {
   //...
}

您可以创建一个配置类,以基于占位符(在此示例中为foo)返回适当的实现:

@Configuration
public class FooDaoConfiguration {

    @Value("${foo}")
    private String foo;

    @Autowired
    private BeanFactory beanFactory;

    @Bean
    @Primary
    public FooDao fooDao() {
        return beanFactory.getBean(foo, FooDao.class);
    }

}

然后您可以在属性文件中切换实现:

#foo=firstFooDao
foo=secondFooDao

这样,两个实现都由spring管理-与链接文档中的示例不同,在返回的对象中,使用非spring工厂构造了返回的对象。在这种情况下,所有bean都在春天之前实例化。配置类选择一个。


1
投票

您可以在bean的class属性中使用属性占位符,因此,如果您有明智的命名约定,则可以使用类似的东西]]

<bean id="customerDao" class="com.example.dao.${dao.type}.CustomerDao">

而不是使用工厂bean。


0
投票

照常使用@Component或XML在Spring上下文中创建DAO实例声明。假设它们都继承了一个公共接口,那么以后您可以使用列表来收集它们。有关此类型收集机制的更多信息,请参见此链接:http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation


0
投票

Spring Boot:AbstractFactoryBean的用法

© www.soinside.com 2019 - 2024. All rights reserved.