Spring-高级装配
环境与 profile
开发软件过程中,不同的环境可能需要不同的配置,Spring 提供的解决方案可以避免重新构建应用。
配置 profile bean
在 Java 配置中,可以使用 @Profile 注解某个 bean 属于哪一个 profile。在 Spring 3.1 中,只能在类级别使用 @Profile 注解;从 Spring 3.2 开始,可以在方法级别上使用 @Profile 注解,与 @Bean 注解同一使用。
在 XML 中配置 profile,可以通过 <beans> 元素的 profile 属性。还可以在根 <beans> 元素中嵌套定义 <beans> 元素,这样能将所有的 profile bean 定义放到同一个 XML 文件中。
激活 profile
Spring 在确定哪个 profile 处于激活状态时,需要依赖两个独立的属性, spring.profiles.active 和 spring.profiles.default,其中优先 spring.profiles.active。有多种方式来设置这两个属性:
- 作为 DispatcherServlet 的初始化参数
- 作为 Web 应用的上下文参数
- 作为 JNDI 条目
- 作为环境变量
- 作为 JVM 的系统属性
- 在集成测试类上,使用 @ActiveProfiles 注解设置
处理自动装配的歧义性
指定首选 bean
@Primary 注解能够与 @Component 注解组合用在组件扫描的 bean 上,也可以与 @Bean 注解组合用在 Java 配置的 bean 声明中;如果使用 XML 配置 bean,<bean> 元素通过其 primary 属性指定首选的 bean。
使用限定符
@Qualifier 注解可以与 @Autowired 注解和 @Inject 注解协同使用;当使用 Java 配置显式定义 bean 的时候,@Qualifier 也可以与 @Bean 注解一起使用
bean 的作用域
Spring 定义了多种作用域:
- 单例(Singleton):在整个应用中,只创建 bean 的一个实例。默认作用域
- 原型(Prototype):每次注入或者通过 Spring 应用上下文获取的时候,都会创建一个新的 bean 实例。
- 会话(Session):在 Web 应用中,为每个会话创建一个 bean 实例。
- 请求(Request):在 Web 应用中,为每个请求创建一个 bean 实例。
应用: @Scope 注解(可以与 @Component 或 @Bean 一起使用)、XML 中 <;bean> 元素的 scope 属性
运行时求值
Spring 提供了两种在运行时求值的方式:
- 属性占位符,形式:${…}
- Spring 表达式语言(SpEL),形式:#{…}
SpEL 拥有很多特性,包括:
- 使用 bean 的 ID 来引用 bean;
- 调用方法和访问对象的属性;
- 对值进行算术、关系和逻辑运算;
- 正则表达式匹配;
- 集合操作。
SpEL 样例:
- 在表达式中使用类型:#{T(System).currentTimeMills()}
计算当前时间的毫秒值,T() 表达式会将 java.lang.System 视为 Java 中对应的类型。 - 浮点值:#{3.14159}
- 科学计数法:#{9.87E4} ,相当于 98700
- String 类型的字面值:#{‘Hello’}
- Boolean 类型的值:#{false}
- 引用 bean:#{student}
- 引用 bean 属性:#{student.name}
- 引用 bean 方法: #{student.study()}
- ?. 运算符:
#{student.getEmail()?.toUpperCase()}。?. 运算符能够在访问它右边的内容之前确保它所对应的元素不是 null 。是 null 的话不会调用 toUpperCase() 方法,并且返回值为 null - 正则表达式:
#{student.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'} - 集合:
- [] 运算符(从集合或数组中按照索引获取元素):#{student.teachers[0].name}
- .?[] 运算符(对集合进行过滤,得到集合的一个子集):
#{student.teachers.?[name eq 'Allen']} - .^[] 和 .$[](分别用来在集合查询第一个匹配项和最后一个匹配项)
- 投影运算符 .![] (从集合的每个成员中选择特定的属性放到另外一个集合中):
#{student.teachers.![name]}