高级装配Bean目录
一、高级装配bean概述
高级装配Bean的一些原理,后续再具体研究。
二、条件化的Bean声明
Spring 4 引入了一个新的 @Conditional 注解,它可以用到带有 @Bean 注解的方法上。如果给定的条件计算结果为 true,就会创建这个bean,否则的话,这个bean会被忽略。
它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
—实现Condition接口
public class WayConditionV2 implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Linux")){
return true;
}
return false;
}
}
public class WayConditionV1 implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Windows")){
return true;
}
return false;
}
}
—Bean对象
public class StartWay {
private String name;
private String value;
StartWay(){}
StartWay(String name,String value){
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
—按照条件装配到Bean,注解的重写方法返回true,那么就可以创建这个Bean。否则是不创建的。
@Configuration
public class ConditionConfig {
//Conditional接口是需要重写,实现对应功能,来确定结果
@Conditional({WayConditionV1.class})
@Bean("startWay1")
public StartWay way1(){
return new StartWay("way1","");
}
@Conditional({WayConditionV2.class})
@Bean("startWay2")
public StartWay way2(){
return new StartWay("way2","");
}
}
三、Bean的作用域
一个Bean创建后放入spring容器,其实就是在ConcurrentHashMap存储。
对于singleton单例作用域,由spring来管理整个Bean的生命周期(创建、初始化、销毁)。非单例作用域,spring负责创建和初始化后,得到Bean实例交给客户端管理。
3.1 singleton单例作用域
容器初始化时创建Bean实例,在整个容器的生命周期内只创建这个Bean,单例的。
在同一个Spring容器中,只会缓存bean的唯一对象,所有通过容器获取这个bean的方式,最终拿到的都是同一个对象。
-----注意:如果Bean的状态(属性)变化【如全局变量场景】,那么会有线程安全问题。
3.2 prototype原型作用域
容器初始化时不创建Bean实例,在每次请求时创建一个新的Bean实例,并返回。对象的销毁和资源回收由使用者负责。
针对单例作用域和Bean的属性会发生改变----没有线程安全问题,可以采用prototype作用域。
<bean id="xmlDescImplV2" class="com.wwy.JavaBean.XmlConfigBean.XmlDescImplV2" scope="prototype">
Spring容器不会为这个对象做销毁工作,可以通过Spring提供的接口,自定义一个后处理器,然后将这些bean的引用存储在这个后处理器中,当容器回调这个后处理器的方法时,我们可以在方法中通过提前存储的bean的引用,将它们销毁。
3.3 request作用域
request作用域将bean的使用范围限定在一个http请求中,对于每一个请求,都会单独创建一个bean,若请求结束,bean也会随之销毁—不存在线程安全问题。
使用@RequestScope注解即可使用此作用域:
基于xml文件,则通过bean的scope配置项:
<bean id="userPreferences" class="com.wwy.UserPreferences" scope="request"/>
3.4 session作用域
对于每一个http会话,Spring容器都会创建一个单独的bean,若session被销毁,则bean也随之销毁。每一个session可以对应于多个request,所以修改session的bean,那么存在线程安全问题。
使用@SessionScope注解即可使用此作用域:
基于xml文件,则通过bean的scope配置项:
<bean id="userPreferences" class="com.wwy.UserPreferences" scope="session"/>
3.5 globaleSession作用域
只适用于基于portlet的web应用程序,少见。