故意将Spring bean设置为null

Lun*_*kon 34 java spring

我正在使用Spring将JMS连接工厂注入到我的Java应用程序中.由于这个工厂只在生产环境中需要,而不是在我开发的时候,我把bean定义放到一个单独的XML中,我将其包含在我的主applicationContext.xml中.在生产环境中,此额外文件包含常规bean定义.在我的本地开发环境中,我希望这个bean为null.当Spring遇到它不知道的引用ID时,试图简单地删除bean定义,显然会导致错误.

所以我尝试创建一个只返回null的工厂bean.如果我这样做,Spring(2.5.x)会抱怨工厂返回null,尽管基于FactoryBean接口的Spring API文档,我希望这可以工作(参见Spring API doc).

XML看起来像这样:

<bean id="jmsConnectionFactoryFactory" class="de.airlinesim.jms.NullJmsConnectionFactoryFactory" />

<bean id="jmsConnectionFactory" factory-bean="jmsConnectionFactoryFactory" factory-method="getObject"/>
Run Code Online (Sandbox Code Playgroud)

这样做的"正确"方法是什么?

Ste*_*n C 30

我很确定Spring不会允许你null与bean id或别名相关联.您可以通过将属性设置为null来处理此问题.

这是你在Spring 2.5中做到这一点的方法

<bean class="ExampleBean">
    <property name="email"><null/></property>
</bean>
Run Code Online (Sandbox Code Playgroud)

在Spring 3.0中,您还应该能够使用Spring表达式语言(SpEL) ; 例如

<bean class="ExampleBean">
    <property name="email" value="#{ null }"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

或任何计算结果的SpEL表达式null.

如果您使用占位符配置器,您甚至可以这样做:

<bean class="ExampleBean">
    <property name="email" value="#{ ${some.prop} }`"/>
</bean>
Run Code Online (Sandbox Code Playgroud)

哪里some.prop可以在属性文件中定义为:

some.prop=null
Run Code Online (Sandbox Code Playgroud)

要么

some.prop=some.bean.id
Run Code Online (Sandbox Code Playgroud)


axt*_*avt 22

factory-bean/ factory-method不起作用null,但自定义FactoryBean实现工作正常:

public class NullFactoryBean implements FactoryBean<Void> {

    public Void getObject() throws Exception {
        return null;
    }

    public Class<? extends Void> getObjectType() {
        return null;
    }

    public boolean isSingleton() {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)
<bean id="jmsConnectionFactory" class = "com.sample.NullFactoryBean" />
Run Code Online (Sandbox Code Playgroud)

  • 有一个开放的功能请求,但已经在那里坐了2年...投票可能会有所帮助:http://jira.springframework.org/browse/SPR-5320 (6认同)

Ger*_*tra 12

对于遇到此问题的任何人,请记住,只需将@Autowired注释设置为可选即可(例如,如果没有找到符合条件的bean,Spring将保留引用null).

@Autowired(required = false)
private SomeClass someBean
Run Code Online (Sandbox Code Playgroud)

请注意,您必须在引用bean的每个位置执行此操作,这可能比创建如上所述的null-factory更麻烦.


小智 7

对于遇到此问题的其他人:如果您使用 Java 8,另一种方法是使用Supplier函数接口来包装可能为 null 的 bean:

@Bean
@Scope("singleton")
public Supplier<SomeBean> getSomeBean() {
  SomeBean myBean = null;  // or can set to a SomeBean instance
  return () -> myBean;
}
Run Code Online (Sandbox Code Playgroud)

使用@Autowired构造函数注入看起来像:

private SomeBean someBean;

@Autowired
SomeService(Supplier<SomeBean> someBeanSupplier) {
    this.someBean = someBeanSupplier.get();
}
Run Code Online (Sandbox Code Playgroud)

那么someBeanin 中的字段SomeService可以为空,也可以为非空。