Re recognize the Scope of Spring

Posted by B of W on Fri, 04 Mar 2022 21:50:05 +0100

What is Spring's rope

Scope, also known as scope, in Spring IoC container, refers to the request visibility range of the Bean object it creates relative to other Bean objects. The Spring IoC container has the following scopes: basic scope (singleton, prototype), Web scope (reqeust, session, globalsession), and custom scope< br/>

  1. singleton is configurablebeanfactory SCOPE_ singleton, single instance mode, also the default mode< br/>
  2. prototype is configurablebeanfactory SCOPE_ prototype, multi case mode< br/>
  3. Request is webapplicationcontext SCOPE_ Request means that in an http request, the annotated beans are the same Bean, and different requests are different beans< br/>
  4. Session is webapplicationcontext SCOPE_ Session means that in an http session, the annotated beans are the same Bean, and different sessions are different beans< br/>

prototype trap

Normally, singleton is a single instance and prototype is a multi instance. If you use the prototype attribute directly at the entry location, there will be multiple corresponding instances. However, if the class object modified by prototype is the corresponding attribute of other singleton modified objects, prototype cannot achieve the real desired result. Because it should be a multi instance object, it has been given in memory when the single instance object is loaded for the first time< br/>
@Correct usage of Scope("prototype") -- solving multiple problems of Bean<br/>
Accurate use of prototype in Spring<br/>
But in fact, prototype is not wrong, nor is there a problem, but there is a problem with our way of use< br/>

How to deal with the problem that the prototype attribute does not work

  1. Under normal circumstances, the true multi instance mode can be realized by directly using @ Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS) or @ Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS). However, if there is asynchronous operation in the service and the http related to the request is lost, an error will be reported
    <!-- more -->

    Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
    I am getting the above error when i am injecting a spring dependency and using it inside MessageListener bean
  2. Directly use SpringBeanUtil to obtain the corresponding bean< br/>
    In the case of nested Scope, getapplicationcontext() GetBean () method to obtain the bean object. If the object is prototype, multiple objects will be generated according to the bean generation strategy< br/>
  3. Either of the above two methods may have problems, or they don't feel very elegant. Here's another way< br/>
ObjectFactory<BalanceLogic> balanceLogicFactory

Direct use < br / >

BalanceLogic balanceLogic = balanceLogicFactory.getObject();

Topics: Java Spring