在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;
}