Spring Java Config和Prototype Beans

时间:2013-07-18 21:23:25

标签: java spring

我已经将我的代码从Spring的XML配置移到了Java Configuration。我有一切工作,但我有一个关于我如何实现原型bean的问题 - 主要是,虽然我正在做的工作,这是最好的方法吗?不知怎的,它感觉不舒服!

我用这种方式写了bean类:

@Component
@Scope("prototype")
public class ProtoBean {
    ...
}

然后使用bean - 这是我不确定的部分,虽然它确实有效:

@Component
public class BeanUser implements ApplicationContextAware {
    ApplicationContext context;

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

    public void getProtoBean() {
         ProtoBean protoBean = context.getBean(ProtoBean.class);
    }
}

这让我得到了一个原型bean,在单元测试中我只是模拟了上下文,用mock调用了setApplicationContext,并且对mock的getBean调用返回了一个模拟ProtoBean。一切都很好。

我是通过使用工厂在XML中完成的,但这似乎不太好用,所以这就是我最终的地方。但有没有办法在没有上下文的情况下做到这一点?或者只是更好的方式?

谢谢!

1 个答案:

答案 0 :(得分:1)

我认为Spring XML与基于Java的配置不是一个问题,而是匹配的依赖范围之一。由于Spring只能在创建时对单例范围的bean执行依赖注入,因此必须按需查找原型范围的bean。当然,当前的bean查找方法有效,但会对ApplicationContext产生依赖性。我可以提出一些其他的可能性,但问题的根源实际上是生成ProtoBean所涉及的内容,以及你应该接受的权衡。

您可以使BeanUser本身具有原型范围,这将允许您将ProtoBean作为成员连接。当然,权衡的是你现在在BeanUser的客户端上遇到了同样的问题,但有时这不是问题。

另一条路径可能是使用类似单一作用域的ProtoBeanFactory来提供ProtoBean实例,并在ProtoBeanFactory中隐藏依赖项查找。

最后,您可以使用范围代理bean来有效地隐藏工厂。它使用AOP来做到这一点,而且并不总是让别人清楚你有什么样的伏都教。使用XML,您可以在bean声明中使用<aop:scoped-proxy/>。对于您使用的注释:

@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype")