简体   繁体   English

Spring作用域实例变量的用法

[英]Spring scope usage for instance variables

We are implementing spring services and the @Webservice layer is singleton and it calls a 'Service' layer which is a prototype. 我们正在实现spring服务,@ Webservice层是单例,它称为原型的“ Service”层。 The Service layer has a lot of instance variables so, thought making it a prototype would be ideal, but, it looks like that prototype is instantiated only one time because @Webservice layer is singleton. Service层具有很多实例变量,因此,认为使其成为原型将是理想的选择,但是,由于@Webservice层是单例,因此看起来该原型仅被实例化了一次。

What type of @Scope works for us? 什么类型的@Scope对我们有用? We have a lot of instance variables on service layer and it is hard for us to make them local to method as a lot of code needs to change because of this. 服务层上有很多实例变量,由于很多代码需要更改,因此很难将它们设置为方法的局部变量。

If I make all layers as singleton, do two thread share the instance variables? 如果我将所有层都设为单例,那么两个线程是否共享实例变量?

Given a singleton bean with an injection target, Spring will initialize the bean and inject the field/method/constructor immediately. 给定具有注入目标的单例bean,Spring将初始化该bean并立即注入field / method / constructor。 If that injection target is a prototype bean, Spring will do so exactly once. 如果该注入目标是原型Bean,则Spring只会执行一次。

Presumably, you want a new prototype bean on each action or event that your singleton handles. 大概,您希望在单例处理的每个动作或事件上都有一个新的原型bean。 You'll need an AOP scoped proxy. 您将需要一个AOP范围的代理。 This is documented in the Spring chapter on Scoped proxies and dependencies . 在有关作用域代理和依赖项的Spring章节中对此进行了记录。 With a configured scoped proxy, Spring will inject a proxy instead of a prototype bean. 使用配置的作用域代理,Spring将注入一个代理而不是原型bean。

The proxy itself will delegate all calls to it to a prototype bean, a new instance each time. 代理本身会将对它的所有调用委派给原型Bean,每次都是一个新实例。

With annotation configuration, you can configure your @Bean or @Component with 通过注释配置,您可以使用以下命令配置@Bean@Component

@Scope(scopeName = BeanDefinition.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)

This tells Spring to configure the bean with a proxy that will inherit the target's actual class type and be a prototype. 这告诉Spring用代理配置bean,该代理将继承目标的实际类类型并成为原型。

When you then inject it 然后注入时

@Autowired
private MyPrototypeBean bean;

bean will hold a reference to a proxy object. bean将保存对代理对象的引用。 You can then invoke methods 然后可以调用方法

bean.method();

and that will delegate to a new instance. 这将委派给一个新实例。 This means that each call 这意味着每次通话

bean.method();
bean.method();
bean.method();

will operate one a new instance, three new instances in the example above. 将操作一个新实例,在上面的示例中将操作三个新实例。 If you only want one instance to invoke those methods, you can extract it from the proxy. 如果只希望一个实例调用这些方法,则可以从代理中提取它。 See the solution provided here 请参阅此处提供的解决方案

MyPrototypeBean target = null;
if (AopUtils.isJdkDynamicProxy(proxy)) {
    target = (MyPrototypeBean) ((Advised)proxy).getTargetSource().getTarget();
} // won't work for CGLIB classes AFAIK (gotta search)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM