简体   繁体   中英

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. 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.

What type of @Scope works for us? 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. If that injection target is a prototype bean, Spring will do so exactly once.

Presumably, you want a new prototype bean on each action or event that your singleton handles. You'll need an AOP scoped proxy. This is documented in the Spring chapter on Scoped proxies and dependencies . With a configured scoped proxy, Spring will inject a proxy instead of a prototype bean.

The proxy itself will delegate all calls to it to a prototype bean, a new instance each time.

With annotation configuration, you can configure your @Bean or @Component with

@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.

When you then inject it

@Autowired
private MyPrototypeBean bean;

bean will hold a reference to a proxy object. 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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