2010-05-13 43 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