如何在Spring中避免applicationContext.getBean?

时间:2016-11-25 12:05:00

标签: java spring dependency-injection

我有一个 Bar 类,如下所示:

class Bar implements ApplicationContextAware {

    ApplicationContext applicationContext;

    void barFoo() {
        final Foo foo = applicationContext.getBean(Foo.class);
        foo.doSomeWork();
        foo.shutDownProperly();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

foo 在我的配置中定义如下:

<bean id="foo" class="biz.tugay.Foo" scope="prototype"/>

因为,Singleton Foo不能正常工作,每次都必须正确关闭..

我认为getBean打破了整个&#34;依赖注入&#34; /&#34;可测试&#34;原理。

但我如何&#34; 注入&#34; a&#34; 原型Foo &#34;进入&#34; 酒吧&#34;对于&#34; barFoo &#34;方法

2 个答案:

答案 0 :(得分:3)

因此,您需要在单例bean中注入原型bean,并在每次调用单例方法时使用新版本的原型bean。

您可以尝试使用ScopedProxyFactoryBean,但Spring Framework Reference Manual建议使用查找方法注入。

Bar课程将成为:

class Bar implements ApplicationContextAware {

    ApplicationContext applicationContext;

    void barFoo() {
        final Foo foo = createFoo();
        foo.doSomeWork();
        foo.shutDownProperly();
    }

    protected abstract Foo createFoo(); // Implementation will be provided by Spring Framework
}

您只需要在bean定义中声明该方法:

<bean id="foo" class="biz.tugay.Foo" scope="prototype"/>
<bean id="bar" class="biz.tugay.Bar">
    <lookup-method name="createFoo" bean="command"/>
</bean>

参考文献(强调我的):

  

具有原型bean依赖性的单例bean
..   但是,假设您希望单例范围的bean获取原型范围的新实例   bean在运行时反复出现。你不能依赖注入原型范围的bean到你的   单例bean,因为当Spring容器实例化时,只发生一次注入   单例bean并解析并注入其依赖项。 如果您需要原型的新实例   bean在运行时不止一次,请参阅“方法注入”一节

  

查找方法注入

     

查找方法注入是容器覆盖容器托管bean上的方法的能力,   返回容器中另一个命名bean的查找结果。查找通常涉及到   原型豆[...]。 Spring框架实现了   这种方法通过使用CGLIB库中的字节码生成来动态生成a   覆盖该方法的子类。

答案 1 :(得分:1)

您可以使用org.springframework.beans.factory.ObjectFactory:

class Bar {

@Autowired
private ObjectFactory<Foo> fooObjectFactory;

}

然后你可以通过以下方式获得Foo对象:

 Foo foo = fooObjectFactory.getObject();