天天看點

spring bean scope

在spring bean作用域:singleton(單例)、prototype(原型),

request、session,專用于Web應用程式上下文的Bean。

環境:作者本人使用spring boot 1.5.6測試。

1、singleton 作用域

spring預設使用singleton單例模式

當一個bean的 作用域設定為singleton, 那麼Spring IOC容器中隻會存在一個共享的bean執行個體,并且所有對bean的請求,隻要id與該bean定義相比對,則隻會傳回bean的同一執行個體。換言之,當把 一個bean定義設定為singleton作用域時,Spring IOC容器隻會建立該bean定義的唯一執行個體。這個單一執行個體會被存儲到單例緩存(singleton cache)中,并且所有針對該bean的後續請求和引用都 将傳回被緩存的對象執行個體,這裡要注意的是singleton作用域和GOF設計模式中的單例是完全不同的,單例設計模式表示一個ClassLoader中 隻有一個class存在,而這裡的singleton則表示一個容器對應一個bean,也就是說當一個bean被辨別為singleton時 候,spring的IOC容器中隻會存在一個該bean。

預設就是singleton,不用寫。

@Scope标注在spring的元件類(使用了@Component等等),或者使用了@Bean的方法上

2、prototype原型模式:

每次擷取的是一個新的對象

情況2.1:單例對象使用多例對象

方式2.1.1:不使用代理建立

public class A{
    @Autowired  
    private ApplicationContext applicationContext;
    private B b;
    void fun(){
        b = applicationContext.getBean(B.class);
   }
 }

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class B{}
           

通過getBean擷取新的多例對象,否則擷取的是同一個多例對象

方式2.1.2:使用代理建立(推薦)

public class A{
    @Autowired  
    private B b;
 }

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class B{}
           

使用代理模式,代理目标類。在單例對象a裡面通過注入@Autowired多例對象b,每次注入的是一個新的多例對象b。

情況2.2:多例對象使用多例對象

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class A{
@Autowired
    private B b;
 }
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class B{}
           

每次注入的是一個新的多例對象b

request

request表示每一次HTTP請求都會産生一個新的bean,該bean僅在目前HTTP request内有效

@RequestScope
public class B{}
           
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope("request")
public @interface RequestScope {
    @AliasFor(
        annotation = Scope.class
    )
    ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
           

3、session

session作用域表示不同session的HTTP請求會産生一個新的bean,該bean僅在目前HTTP session内有效

@SessionScope
public class B{}
           
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope("session")
public @interface SessionScope {
    @AliasFor(
        annotation = Scope.class
    )
    ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}