Spring实战(第四版) 第三章 高级装配
1、环境与Profile
配置profile bean
- 首先要将所有不同的bean定义整理到一个或多个profile之中,在将应用部署到每个环境时,要确保对应的profile处于激活状态
- @Profile,指定某个bean属于哪一个profile @Profile("dev")
激活profile
有两个属性:spring.profiles.active spring.profiles.default
2、条件化bean
根据条件才创建bean @Conditional注解
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MagicConfig {
@Bean
@Conditional(MagicExistsCondition.class)
public MagicBean magicBean() {
return new MagicBean();
}
}
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class MagicExistsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
return env.containsProperty("magic");
}
}
-
ConditionContext接口
- getRegistry() 可检查bean定义
- getBeanFactory() 可检查bean是否存在、探查bean属性
- getEnviroment() 可检查环境变量是否存在以及它的值
- getResourceLoader() 返回ResourceLoader加载的资源(比如磁盘资源)
- getClassLoader() 检查类是否存在
-
AnnotatedTypeMetadata接口
- isAnnotated() 判断带有@Bean注解的方法是不是还有其他注解
- getAnnotationAttributes()
- getAllAnnotationAttributes()
3、处理自动装配的歧义性
处理有多个可供装配的对象的情况
首选bean
- @Primary标签
@Component
@Primary
public class IceCream implements Dessert {}
限定自动装配的bean
- @Qualifier注解,设置的参数就是想要注入的bean的ID。
@Component
@Qualifier("cold")
public class IceCream implements Dessert {}
@Autowired
@Qualifier("cold")
public void setDessert(Dessert dessert) {
this.dessert = dessert;
}
- 不允许在同一个条目上重复出现相同类型的多个注解,也可以自己创建标签进行注解
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.Type})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold {}
4、bean的作用域
默认情况下,Spring应用上下文所有bean都是作为以单例的形式创建的。不管给定一个bean被注入多少次,每次注入的都是同一个实例。
- 单例:在整个应用中,只创建bean的一个实例。
- 原型:每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
- 会话:在Web应用中,为每个会话创建一个bean实例。
- 请求:在Web应用中,为每个请求创建一个bean实例。
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad {}
使用会话和请求作用域
- 如果有个购物车类,需要为每个用户都生成一个实例,同时有一个商店类,会为购物车提供相关服务。
- 但是商店类是单例生成的,在Spring应用上下文加载时创建,而购物车类不是,这时会创建一个代理,注入到商店类里。
@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES)
public ShoppingCart cart() {}
@Component
public calss StoreService {
@Autowired
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
}
5、运行时值注入
注入外部值
- @PropertySource注解,引入外部文件,从Environment实例中可以获取外部文件中的配置
- 使用${...}引入外部信息
public class BlankDisc(@Value("$disc.title") String title, @Value("${disc.artist}") String artist) {
this.title = title;
this.artist = artist;
}
使用Spring表达式语言进行装配
- 使用bean的ID来引用bean
- 调用方法和访问对象的属性
- 对值进行算是、关系和逻辑运算
- 正则表达式匹配
- 集合操作
使用方法是 #{}
- #
- #
- #
- #
- #
- #
- #
浙公网安备 33010602011771号