关于spring:重新认识Spring的Scope

51次阅读

共计 1985 个字符,预计需要花费 5 分钟才能阅读完成。

Spring 的 Sope 是什么

Scope,也称作用域,在 Spring IoC 容器是指其创立的 Bean 对象绝对于其余 Bean 对象的申请可见范畴。在 Spring IoC 容器中具备以下几种作用域:根本作用域(singleton、prototype),Web 作用域(reqeust、session、globalsession),自定义作用域。<br/>

  1. singletonConfigurableBeanFactory.SCOPE_SINGLETON, 单例模式,也为默认模式;<br/>
  2. prototypeConfigurableBeanFactory.SCOPE_PROTOTYPE, 多例模式;<br/>
  3. requestWebApplicationContext.SCOPE_REQUEST, 示意在一次 http 申请中,被注解的 Bean 都是同一个 Bean,不同的申请是不同的 Bean;<br/>
  4. sessonWebApplicationContext.SCOPE_SESSION, 示意在一次 http 会话中,被注解的 Bean 都是同一个 Bean,不同的会话是不同的 Bean;<br/>

prototype 陷阱

失常状况下 singleton 为单例,prototype为多例,若间接在入口地位即应用 prototype 属性,那么对应的实例的确会有多个。然而若 prototype 润饰的类对象为其余 singleton 润饰的对象对应的属性,则 prototype 起不到真正的想要后果。因为本应该为多例的对象,被单例对象首次加载的时候曾经赋予在内存里.<br/>
@Scope(“prototype”)的正确用法——解决 Bean 的多例问题 <br/>
Spring 中原型 prototype 的精确应用 <br/>
但实际上 prototype 并不是不对,也不是出了问题,而是咱们的应用形式有问题。<br/>

如何解决 prototype 属性不起效的问题

  1. 失常状况下,间接应用 @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS),能够实现真正的多例模式。然而若业务内存在异步操作,且申请相干的 http 失落,则会报错.
    <!– 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. 间接应用 SpringBeanUtil 获取对应 Bean;<br/>
    对于嵌套 Scope 情景,通过 getApplicationContext().getBean() 形式,获取 bean 对象,若对象为prototype,则会依照 Bean 的生成策略,生成多例对象。<br/>
  3. 下面的两种形式,要么可能存在问题,要么感觉不怎么优雅。这里还有一个办法。<br/>
@Autowired
ObjectFactory<BalanceLogic> balanceLogicFactory

间接应用 <br/>

BalanceLogic balanceLogic = balanceLogicFactory.getObject();

https://yannis.club/

正文完
 0