(原创)Spring 依赖注入 - 通过控制作用域解决 bean 的重用或污染问题

目录

一、背景

二、分类

三、控制方式

1.自动装配和 JavaConfig 的场景

2.XML配置的场景

3.在非 web 环境中注入 web 环境的 bean


一、背景

在默认情况下,Spring 上下文中所有的 bean 都是以单例的形式创建。但是在一些场景中,会发现一个 bean 是可能带有状态的,因此重用并不安全。或者是某些场景下,希望 bean 能带有某些不同的值,如会话中不同用户的信息。这时候就需要控制 bean 的作用域了。

二、分类

Spring 中定义了 bean 有以下几个作用域:

  • 单例(singleton):整个上下文中,每个 bean 只会有一个实例。
  • 原型(prototype):每次从上下文获取的都会创建一个新的 bean 实例。
  • 请求(request):在 Web 应用中,为每个请求创建一个 bean 实例。
  • 会话(session):在 Web 应用中,为每个会话创建一个 bean 实例。
  • 全局会话(globalSession):用于 Porlet,同一个全局 Session 共享一个 bean, 仅用于 WebApplication 环境。

三、控制方式

1.自动装配和 JavaConfig 的场景

我们通过在使用 @Component 或 @Bean 时添加 @Scope 注解来设置其作用域。

例如:

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class People() { ... }

@Component
@Scope(
    value=WebApplicationContext.SCOPE_SESSION,
    proxyMode=ScopedProxyMode.INTERFACES)
public class Person() { ... }

其中,ConfigurableBeanFactory.SCOPE_PROTOTYPE 的值即为 "prototype" ,我们使用常量不叫不容易拼写错误。

2.XML配置的场景

我们通过 <bean> 元素的 scope 属性来设置作用域:

<bean id="people" 
      class="aa.bb.People" 
      scope="prototype" />

<bean id="people" 
      class="aa.bb.People" 
      scope="session" >
    <aop:scoped-proxy proxy-targert-class="false">
</bean>

3.在非 web 环境中注入 web 环境的 bean

在上面的例子中我们可以看到,在 web 作用域中的类型(request、session 和 globalSession)在定义时还会加上一个作用域代理,因为web 类型的作用域是在会话发生时上下文才会进行创建 bean,而非 web 类型作用域的 bean 在一开始便进行创建,此时会发生装配的问题。

于是我们为wed 作用域类型的 bean 创建一个代理类,该代理类暴露出于实际类相同的方法,先将此代理类注入到非web类型的 bean 中,当会话发生时,动态代理会判断实际类处于哪个线程,并进行实际的调用。

因为 Java 语言只支持对接口的动态代理,如果要对类进行动态代理,需要加入 CGLib 库。代理类型也不同,分别为:

自动装配 和 JavaConfig 风格配置:

  • 接口类型:proxyMode=ScopedProxyMode.INTERFACES
  • 类类型:proxyMode=ScopedProxyMode.TARGET_CLASS

XML 风格配置:

  • 接口类型:<aop:scoped-proxy proxy-targert-class="false">
  • 类类型:<aop:scoped-proxy >

 

(原创不易,转载请注明出处!!)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值