一尘不染

可选的Spring bean参考

spring

在我的应用程序中,我正在使用ContextLoaderListener从多个jar中加载上下文文件,方法是:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/contextBeans.xml</param-value>
</context-param>

这意味着我无需导入即可引用其他jar中的bean。

在应用程序中,有多个部署选项,在某些部署中,可以排除jar。为了证明这一点,我希望一些bean引用是可选的。例如:

<bean id="mainAppBean" class="com.someapp.MyApplication">
    <constructor-arg index="0" ref="localBean"/>
     <constructor-arg index="1" ref="optionalBeanReference1"/>
    <constructor-arg index="2" ref="optionalBeanReference2"/>
 </bean>

在上面的示例中,如果未找到引用,我想让optionalBeanReference1等于null(以某种方式将其标记为可选)

可以在Spring完成吗?或你建议使用什么方法来处理动态引用?


阅读 321

收藏
2020-04-19

共3个答案

一尘不染

你建议使用哪种方法来处理动态引用?

我认为@cristian的@Autowired答案是一个很好的答案。如果该类型的bean可用,则将调用setter方法。但是,如果你有多个相同类型的bean,我相信Spring会引发异常。如果由于这个原因或其他原因而无法使用@Autowired,我会看到一些解决方案:

  1. 你可以创建类ApplicationContextAware并自己在上下文中查找Bean:
public void setApplicationContext(ApplicationContext applicationContext) {
    if (applicationContext.containsBean("optionalBeanReference1")) {
        setOptionalBeanReference1(
            (OptionalBeanReference1)applicationContext.bean(
                "optionalBeanReference1");
    }
    ...
}
  1. 你可以反转依赖关系。每个选修课程的可以设置自己的mainAppBean。在某些情况下,当直接依赖会导致循环或其他问题时,我会使用它。
<bean id="optionalBeanReference1" class="com.someapp.SomeClass">
    <constructor-arg index="0" ref="mainAppBean"/>
</bean>

然后在SomeClass中:

public SomeClass(com.someapp.MyApplication mainAppBean) {
    mainAppBean.setOptionalBeanReference1(this);
}
  1. 你可以保持直接依赖关系,然后使用定义的bean导入文件,或者使用工厂bean导入另一个文件,在其中定义bean为空值的文件。
2020-04-19
一尘不染

我最好的猜测是使用autowire -ing与必需的false。不知道如何用XML表示,但是使用注释配置看起来像:

@Autowired(required=false)
2020-04-19
一尘不染

对于最新版本的Spring(已通过spring 4.1进行了测试)以及Java Configuration和Java 8,您可以在参数中使用Optional,并且只有在可用时才自动装配。

@Autowired
public MyApplication(Optional maybeObject) {
// do something with the optional autowired
}

2020-04-19