2010-05-13 48 views
8

我想將FactoryBeans和示波器一起使用。具體來說,我希望由FactoryBean創建並返回的對象被放置到指定的(可能是自定義的)作用域中。問題是,這樣做的以下內容:在的FactoryBean本身被作用域Spring FactoryBean和示波器一起工作

<bean class="x.y.z.TestFactoryBean" scope="test" /> 

結果,並具有由工廠創建的對象上有些不可預知的行爲。我明白這是爲什麼;工廠本身就是一流的春季管理的豆類,並擁有自己的生命週期。但是,我無法找到一種方法來指定從工廠返回的對象本身應該被作用域。

在另一方面,這不正是我想要的(只要TestFactoryBean沒有實現FactoryBean接口):

<bean class="x.y.z.TestFactoryBean" name="testFactory"> 
<bean class="x.y.z.TestBean" factory-bean="testFactory" 
     factory-method="getObject" scope="test" /> 

所以真正的問題是,如何才能讓春天的行爲像它對於上面的第二個例子,但使用真正的FactoryBeans?

回答

6

您不能輕易在從FactoryBean返回的bean上使用自定義作用域。

從Spring的Java documentation

的FactoryBean可以支持單身和原型

如果你想FactoryBean的返回豆有原型的範圍,那麼你就必須實現isSingleton()方法是這樣:

public class TestFactoryBean implements FactoryBean<TestBean> { 

    // the rest of the required methods are removed for simplicity reasons.. 

    public boolean isSingleton() { 
     return false; 
    } 
} 

要支持自定義範圍,要自己實現邏輯,它不會很直觀,因爲FactoryBean只提供了isSingleton()方法。對於具有自定義範圍的bean,我寧願推薦使用另一個解決方案,而不是FactoryBean

希望這會有所幫助!

+1

你可以在春季自定義幾乎所有的東西,所以我猜它有可能以某種方式,但它可能會涉及到一些非常深的挖掘(使用自定義應用程序上下文)或類似的東西。但我在這裏猜測 – 2010-05-17 19:42:54

+0

我同意並更新了我的答案。 – Espen 2010-05-25 19:01:30

2

我使用自定義持有bean解決了同樣的問題。

廠豆:

@Component 
@Configurable() 
public class EventBusFactory implements FactoryBean<EventBus> { 
    @Override 
    public EventBus getObject() throws Exception { 
     return new SimpleEventBus(); 
    } 

    @Override 
    public Class<?> getObjectType() { 
     return EventBus.class; 
    } 

    @Override 
    public boolean isSingleton() { 
     return false; 
    } 
} 

豆架:

@Configurable 
@Component 
@Scope("session") 
public class EventBusHolder { 

    @Autowired 
    private EventBus eventBus; 

    public EventBus getEventBus() { 
     return eventBus; 
    } 

    public void setEventBus(EventBus eventBus) { 
     this.eventBus = eventBus; 
    } 
} 

然後我用的支架,而不是所需要的實體。

@Component 
@Configurable 
@Scope("session") 
public class UicPlaceController extends PlaceController { 

    @Autowired 
    public UicPlaceController(EventBusHolder eventBus) { 
     super(eventBus.getEventBus()); 
    } 
    ... 
} 

該解決方案看起來有點醜陋,但它仍然解決了這個問題。

+0

我想這與持有人的工作可以改善,但現在它適合我。 – uthark 2011-12-30 05:19:10