2016-11-25 138 views
0

我有一个类酒吧实现如下:如何避免在Spring中使用applicationContext.getBean?

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; 
    } 
} 

而且在我的配置定义如下:

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

因为,一个Singleton富不会做的工作做好并且它必须每次都关闭。

我认为getBean打破了整个“依赖注入n“/”可测试“原则。

但我怎么 “注入” 一 “原型富” 到 “酒吧” 为 “barFoo” 的方法?

+0

取决于上下文,但你可能要改用单 –

+0

@NickVanderhoven美孚已经原型的原型豆,但酒吧本身单身是很好.. –

回答

1

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

class Bar { 

@Autowired 
private ObjectFactory<Foo> fooObjectFactory; 

} 

那么你可以得到Foo对象:

Foo foo = fooObjectFactory.getObject(); 
+0

的ObjectFactory的所有的实现似乎是私有的内部类并且Autowired似乎不起作用。 –

3

因此,你需要在一个单身注入原型豆一个,并在每次调用单例方法时使用原型bean的新版本。

你可以尝试使用ScopedProxyFactoryBean,但是Spring框架参考手册建议的查找方法注入。

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中,因为这个注入只发生一次,当Spring容器实例化单例bean并解析和注入它的依赖关系时。 如果您在运行时不止一次需要原型 的新实例,请参阅“方法注入”一节

Lookup方法注射

Lookup方法注入容器的覆盖受容器管理的bean方法, 到容器返回查询结果为另一个名为豆的能力。查找通常涉及一个 原型bean [...]。 Spring Framework通过使用CGLIB库中的字节码生成来实现 这种注入方法,以动态生成覆盖该方法的 子类。