Spring IOC_10 bean作用域

作用域

<!-- bean的作用域:singleton、prototype,默认情况下是singleton的
    singleton:在容器启动完成之前就已经创建好对象,获取的所有对象都是同一个。
    prototype:容器启动的时候不会创建bean,只有在获取对象的时候才会创建该对象,每次创建都是一个新的对象 -->
<bean id="person1" class="com.nanborone.bean.Person" scope="prototype">
    <property name="id" value="1"/>
    <property name="name" value="nanborone"/>
    <property name="male" value="true"/>
</bean>

Spring容器会在容器创建的时候针对每一个Bean进行校验,但是Bean的属性在Bean没有真正创建之前是不会进行配置的。单例类型的Bean是容器创建的时候配置成预实例状态的, 其他的Bean都只有在请求的时候,才会创建。

如果开发者主要使用基于构造函数的依赖注入,或者每个bean的作用域都是prototype,那么很有可能出现循环依赖的情况,并且抛出BeanCurrentlyInCreationException

代理作用域

将一个多例的bean B注入到单例bean A时,由于容器启动时装配已经完成,则在使用时通过A每次获得的B其实都是一个实例,失去了多例的作用,可以通过代理作用域的方式实现。

<!-- 在根标签下添加xmlns:aop="http://www.springframework.org/schema/aop" -->
<!-- xsi:schemaLocation中加入http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd -->
<bean id="person1" name="person" class="com.nanborone.bean.Person" >
    <property name="address" ref="address"/>
</bean>
<!-- 将短周期作用域bean注入到长周期作用域bean,通过创建代理的方式实现 -->
<bean id="address" class="com.nanborone.bean.Address" scope="prototype">
	<!-- proxy-target-class:设置为false时启用JDK代理,默认CGLIB代理 -->
    <aop:scoped-proxy/>
</bean>

自定义作用域

定义作用域对象

实现Scope接口并实现方法。
Scope接口有四个方法用于操作对象,例如获取、移除或销毁等操作。

以下方法返回相应作用域的对象,如果它不存在,那么将会返回绑定该作用域的新实例

Object get(String name, ObjectFactory objectFactory)

以下方法从相应作用域中删除对象,删除的对象作为返回值,无法找到对象时返回null

Object remove(String name)

以下方法注册在销毁时或在Scope中的指定对象被销毁时应该执行的回调:

void registerDestructionCallback(String name, Runnable destructionCallback)

以下方法获取相应作用域的区分标识符:

String getConversationId()

通过编程来注册作用域

示例使用SimpleThreadScope,这个例子在Spring中是有实现的,但没有默认注册。
您自定义的作用域也可以通过如下的方式来注册。

Scope simpleThreadScope = new SimpleThreadScope();
// 在Spring容器中注册新Scope,第一个参数是作用域名称,第二个参数是作用域实现对象
context.getBeanFactory().registerScope("thread", simpleThreadScope);

然后,您可以创建符合自定义Scope的作用域规则的bean定义,如下所示:

<bean id="..." class="..." scope="thread">

通过配置来注册作用域

<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
    <property name="scopes">
        <map>
            <entry key="thread">
                <bean class="org.springframework.context.support.SimpleThreadScope"/>
            </entry>
        </map>
    </property>
</bean>

<bean id="person" class="com.nanborone.bean.Person">
    <property name="id" value="1"/>
    <property name="name" value="nanborone"/>
    <property name="male" value="true"/>
    <property name="address" ref="address"/>
</bean>

<bean id="address" class="com.nanborone.bean.Address" scope="thread" >
    <property name="province" value="辽宁"/>
    <property name="city" value="沈阳"/>
    <property name="town" value="浑南"/>
    <aop:scoped-proxy/>
</bean>
发布了15 篇原创文章 · 获赞 0 · 访问量 370

猜你喜欢

转载自blog.csdn.net/weixin_44601009/article/details/104308775
今日推荐