我有一个应用程序,我希望能够基于属性文件中的值切换DAO实现。 Spring FactoryBean接口看起来可以很好地工作,因为我可以通过FactoryBean提供DAO,在其中可以执行基于属性值的切换工作。
但是,this springsource博客文章的最后一段提到了这一警告:
这里重要的一点是,驻留在Spring容器中并享受生命周期挂钩和容器服务的是FactoryBean,而不是分解对象本身。返回的实例是瞬态的-Spring对您从getObject()返回的内容一无所知,并且不会尝试执行任何生命周期挂钩或其他任何操作。
我的DAO对象包含Spring批注@Repository
和@Transactional
。根据以上段落,如果我通过FactoryBean返回DAO实现,这些注释将被忽略吗?如果是这样,什么是确保Spring管理由FactoryBean返回的bean的好方法?
编辑:似乎大多数人都为该问题提供了替代配置解决方案。尽管我愿意接受这些建议(如果好的建议会予以支持),但我的问题实际上与正确使用FactoryBean有关,我将根据这些问题标记正确的答案。
假设您有这样的东西:
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都在春天之前实例化。配置类选择一个。
您可以在bean的class
属性中使用属性占位符,因此,如果您有明智的命名约定,则可以使用类似的东西]]
<bean id="customerDao" class="com.example.dao.${dao.type}.CustomerDao">
而不是使用工厂bean。
照常使用@Component或XML在Spring上下文中创建DAO实例声明。假设它们都继承了一个公共接口,那么以后您可以使用列表来收集它们。有关此类型收集机制的更多信息,请参见此链接:http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-autowired-annotation
Spring Boot:AbstractFactoryBean的用法