如何在Spring中按类型创建bean?

时间:2016-09-06 11:30:18

标签: java spring spring-ioc

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

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

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

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

我的实现将由spring调用

@Autowired
private MyCommonInterfaceImplementation impl;

以这种方式

createInstance(MyCommonInterfaceImplementation.class)

到目前为止,我查看了BeanFactoryFactoryBean,两者似乎都不是我正在寻找的。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

为什么不使用@bean

public static void main(String[] args) {
    String uri = "http://my.test.com/test?param1=ab&param2=cd&param2=ef";
    MultiValueMap<String, String> parameters =
            UriComponentsBuilder.fromUriString(uri).build().getQueryParams();
    List<String> param1 = parameters.get("param1");
    List<String> param2 = parameters.get("param2");
    System.out.println("param1: " + param1.get(0));
    System.out.println("param2: " + param2.get(0) + "," + param2.get(1));
}

答案 1 :(得分:1)

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

如果所有内容都可以是@Autowired,可以是setter,字段或一个构造函数,并且在初始化期间不需要对bean执行任何其他操作,您只需在每个实现上声明注释@Component你的界面。只要您的应用程序中有component scanning活动,这就可以正常工作。结果将是每个组件spring将创建一个可以使用的bean。

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

答案 2 :(得分: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。

为此,您可以使用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的问题。

您也可以根据this SO question调整如何以编程方式添加bean的答案。

答案 3 :(得分:0)

最后,我发现的最佳方法是使用<td> {{addDays(data.invoice_date,data.terms) | date:'dd-MM-yyyy'}}</td> 。例如,我使用了My plunker

但是,因为它非常复杂而且太多魔术&#34;为了从零开始创建bean,我们决定通过ConfigurationClassPostProcessor显式创建这些bean。

感谢您的回答。