我已经将我的代码从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中完成的,但这似乎不太好用,所以这就是我最终的地方。但有没有办法在没有上下文的情况下做到这一点?或者只是更好的方式?
谢谢!
答案 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")