1

在我的 ApplicationContext 中,我创建了几个相同样式的 Bean。所以我有很多重复的代码FactoryBean为每个 bean 编写一个。这些 bean 有一个共同点,实现了所有一个特殊的接口。

我想将所有 bean 创建移到一个工厂。那必须提供这样的方法

<T extends CommonInterface> T createInstance(Class<T> clazz);

在那里,我可以实现创建我的一个特殊 bean 所需的所有实例化。

我的实现将由 spring 调用

@Autowired
private MyCommonInterfaceImplementation impl;

以这种方式

createInstance(MyCommonInterfaceImplementation.class)

到目前为止,我看着BeanFactoryand FactoryBean,两者似乎都不是我正在寻找的。

有什么建议么?

4

4 回答 4

2

为什么不使用@bean

@Bean
public MyCommonInterfaceImplementation getMyCommonInterfaceImplementation(){
    return MyBeanFactory.createInstance(MyCommonInterfaceImplementation.class);
}

//should autowire here
@Autowired
private MyCommonInterfaceImplementation impl;
于 2016-09-06T12:18:42.850 回答
1

基本上,@Bean只有在创建 bean 期间需要一些特殊处理时,才需要在“工厂”上添加注释。

如果一切都可以@Autowired通过 setter、fields 或一个构造函数实现,并且在初始化期间不需要对 bean 执行任何其他操作,则只需@Component在接口的每个实现上声明注释即可。只要您component scanning在应用程序中处于活动状态,这就会起作用。结果是,对于每个组件,spring 都会创建一个您可以使用的 bean。

我在手机上写这个,所以显示代码不是最好的。只需按照一些教程进行操作@ComponentScan,或者如果您需要,请告诉我,我可以通过一个示例来扩充这个答案。

于 2016-09-06T16:13:35.410 回答
0

从 Spring 4.3 开始,您不再需要注释您的 bean 类,您可以让它们通过组件扫描来实例化。

@Configuration @ComponentScan( value = "some.package.path", includeFilters = { @Filter(type = ASSIGNABLE_TYPE, value = { MyClass1.class, MyClass2.class, MyClass3.class }) })

这实际上为那里列出的三个类创建了 bean。该示例也应该在没有过滤器的情况下工作(包中的所有内容都变成了一个 bean)。只要这些类有一个可用于自动装配的构造函数,它就可以工作。我认为不可能过滤特定接口的所有实现然后注册一个bean。

为此,您可以使用 a 做一些事情,ContextListener例如使用反射来找出要实例化的类,然后使用 context.autowire(..) 从您的上下文中注入任何依赖项。有点hacky,但它可能会起作用。

@Override public void onApplicationEvent(ContextRefreshedEvent event) { ApplicationContext context = event.getApplicationContext(); MyClass bean = context .getAutowireCapableBeanFactory() .autowire(MyClass.class, Autowire.BY_NAME.value(), true); ... }

当然,这仍然留下了如何在上下文中注册 bean 的问题。

您也许还可以调整这个关于如何以编程方式添加 bean的SO 问题的答案。

于 2016-09-06T15:35:27.607 回答
0

最后,我发现的最佳方法是使用ConfigurationClassPostProcessor. 例如,我使用了 https://github.com/rinoto/spring-auto-mock

但是,由于从无到有创建 bean 非常复杂且“太神奇”,我们决定通过@Bean.

感谢您的回答。

于 2016-09-07T12:07:32.610 回答