2016-11-25 62 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庫中的字節碼生成來實現 這種注入方法,以動態生成覆蓋該方法的 子類。