我们正在实现spring服务,@ Webservice层是singleton,它调用的是一个'Service'层,它是一个原型。 Service层有很多实例变量,所以认为它是一个原型是理想的,但是,看起来原型只被实例化一次,因为@Webservice层是单例。
什么类型的@Scope适合我们?我们在服务层上有很多实例变量,我们很难将它们作为本地方法,因为很多代码都需要改变。
如果我将所有图层都设为单例,那么两个线程共享实例变量吗?
答案 0 :(得分:4)
给定一个带有注入目标的单例bean,Spring将初始化bean并立即注入field / method / constructor。如果该注入目标是原型bean,Spring将只执行一次。
据推测,您需要在单例处理的每个动作或事件上使用新的原型bean。你需要一个AOP作用域代理。这在Scoped proxies and dependencies的Spring章节中有记载。使用配置的范围代理,Spring将注入代理而不是原型bean。
代理本身会将对它的所有调用委托给原型bean,每次都是一个新实例。
使用注释配置,您可以使用
配置@Bean
或@Component
@Scope(scopeName = BeanDefinition.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
这告诉Spring使用代理配置bean,该代理将继承目标的实际类类型并成为原型。
当你注射它时
@Autowired
private MyPrototypeBean bean;
bean
将保留对代理对象的引用。然后,您可以调用方法
bean.method();
,这将委托给一个新实例。这意味着每次通话
bean.method();
bean.method();
bean.method();
将操作一个新实例,上例中的三个新实例。如果您只想要一个实例来调用这些方法,则可以从代理中提取它。请参阅提供的解决方案here
MyPrototypeBean target = null;
if (AopUtils.isJdkDynamicProxy(proxy)) {
target = (MyPrototypeBean) ((Advised)proxy).getTargetSource().getTarget();
} // won't work for CGLIB classes AFAIK (gotta search)