当前位置: 首页 > 后端技术 > Java

重新认识Spring的Scope

时间:2023-04-02 10:06:10 Java

什么是Spring的SopeScope,又称为作用域,在SpringIoC容器中指的是它创建的Bean对象相对于其他Bean对象的请求可见范围。SpringIoC容器中有以下作用域:基本作用域(单例、原型)、Web作用域(reqeust、session、globalsession)、自定义作用域。
singleton为ConfigurableBeanFactory.SCOPE_SINGLETON,单例模式,也是默认模式;
prototype为ConfigurableBeanFactory.SCOPE_PROTOTYPE,多实例模式;
request为WebApplicationContext.SCOPE_REQUEST,表示在http请求中,注解的bean都是同一个bean,不同的请求是不同的bean;
session是WebApplicationContext.SCOPE_SESSION,表示在一个http会话中,注解的bean都是同一个bean,不同的session是不同的Bean;
prototype陷阱一般情况下,singleton是单实例,prototype是多实例。如果直接在entry位置使用prototype属性,那么确实会有多个对应的实例。但是,如果原型修改的类对象是其他单例修改的对象的对应属性,那么原型将达不到预期的效果。因为应该是多实例的对象,在第一次加载单例对象的时候已经在内存中给定了。
@Scope("prototype")的正确用法——解决多实例的问题Bean
在Spring中准确使用原型
但其实原型没有错,也没有问题,而是我们使用的方式。
如何处理原型属性不起作用的问题?一般情况下,直接使用@Scope(value=WebApplicationContext.SCOPE_REQUEST,proxyMode=ScopedProxyMode.TARGET_CLASS)或者@Scope(value=WebApplicationContext.SCOPE_SESSION,proxyMode=ScopedProxyMode.TARGET_CLASS),就可以实现真正的多实例模式。但是如果业务中有异步操作,请求相关的http丢失了,就会报错。Scope'request'对当前线程不活跃;如果您打算从单例中引用它,请考虑为该bean定义一个作用域代理;嵌套异常是java.lang.IllegalStateException:未找到线程绑定请求:您指的是实际Web请求之外的请求属性,还是在原始接收线程之外处理请求?如果您实际上是在Web请求中操作并且仍然收到此消息,则您的代码可能在DispatcherServlet/DispatcherPortlet之外运行:在这种情况下,请使用RequestContextListener或RequestContextFilter来公开当前请求。在注入依赖并在MessageListenerbean中直接使用SpringBeanUtil获取对应Bean时出现上述错误;
对于嵌套Scope,通过getApplicationContext().getBean()获取bean对象,如果object是prototype,会遵循bean的生成策略,生成多个实例对象。
以上两种方式,要么有问题,要么感觉不太优雅。这是另一种方法。
@AutowiredObjectFactorybalanceLogicFactory直接使用
BalanceLogicbalanceLogic=balanceLogicFactory.getObject();https://yannis.club/