在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。
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
默认就是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;
}