Bean的作用域

来源:互联网 发布:上海证券下载什么软件 编辑:程序博客网 时间:2024/05/17 02:30

在默认情况下,Spring应用上下文中所有的bean都是作为以单例的形式创建的。也就是说,不管给定的一个bean被注入到其他bean多少次,每次所注入的都是同一个实例。

Spring中定义了多种作用域,包括:
1、单例(Singleton):在整个应用中,只创建bean的一个实例.
2、原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例
3、会话(Session):在Web应用中,为每个会话创建一个bean实例
4、请求(request):在Web应用中,为每个请求创建一个bean实例

使用组件扫描来发现和声明bean:

@Component("lonely")@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)//@Scope("prototype") 也是可以的public class SgtPeppers implements CompactDisc {    public void play() {      System.out.println("test");    }}

在JavaConfig中设置作用域

@Configurationpublic class DispactConfig {    @Bean    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)    public CompactDisc compactDisc(){        return new SgtPeppers();    }}

在XML中设置作用域:

 <bean id="cdPlat" class="org.springaction.CDPlat" scope="prototype"/>

二、使用会话和请求作用域

@Component@Scope(value="session",proxyMode = ScopedProxyMode.INTERFACES)public class SgtPeppers implements CompactDisc {    public void play() {      System.out.println("test");    }}

将value设置为session,会为Web应用中的每个会话创建一个bean的实例。

@Componentpublic class Instrument {    @Autowired    public void setSgtPeppers(CompactDisc sgtPeppers) {        this.sgtPeppers = sgtPeppers;    }}

在被依赖的instrument bean,可能是一个单例的bean,它会在Spring应用上下文加载的时候创建,当它创建的时候,Spring会试图将会话范围的sgtPeppers bean注入到构造器或setter方法中,但是会话作用域范围的sgtPeppers bean此时并不存在,直到某个用户进入系统,创建了会话之后,才会出现。并且并不想让Spring注入某个固定的会话bean。所以需要配置proxyMode,使用代理的会话bean。当真正调用会话bean的方法时,代理会对其进行解析并将调用委托给会话作用域内真正的sgtPeppers bean。

proxyMode属性有两个值:
ScopedProxyMode.INTERFACES :如果会话bean是一个接口,该属性值表明这个代理要实现接口,并将调用委托给实现的bean。

ScopedProxyMode.TARGET_CLASS :如果会话Bean是一个具体的类,那就没办法创建基于接口的代理,需要使用该属性值,表明要以继承的方式创建代理。

请求作用域
请求作用域的bean也会遇到相同的装配问题,也应该使用作用域代理的方式进行注入:

@Component@Scope(value="request",proxyMode =ScopedProxyMode.INTERFACES)public class SgtPeppers implements CompactDisc {    public void play() {      System.out.println("test");    }}

在XML中声明作用域代理
需要使用aop命名空间,

 <bean id="sgtPeppers" class="org.springaction.SgtPeppers" scope="session">        <!--默认使用基于具体类的代理-->        <aop:scoped-proxy/>    </bean>

可以将proxy-target-class属性设置为false,要求它生成基于接口的代理:

<bean id="sgtPeppers" class="org.springaction.SgtPeppers" scope="session">        <!--默认使用基于具体类的代理-->        <aop:scoped-proxy proxy-target-class="false"/>    </bean>
原创粉丝点击