一、环境与profile
(1)简述
应用程序在不用的软件环境下可能出现无法正常工作的问题。profile就是为此而生。不同的profile代表不同的软件环境。
(2)配置profile bean
这是3.1版本Spring所映入的功能。要使用profile,你要把所有的bean定义整理到一个或者多个profile中,将应用部署的到每个环境的时候,要确保对应的profile处于激活的状态。
- JavaConfig使用@Profile("自定义环境名")这样的注解来表示,3.1版本只能应用在类级别上,3.2以后你也可以在方法级别上使用该注解。
只有规定的profile激活的时候,相应的bean才会被创建,而没有指定profile的bean始终会被创建。
- XML配置使用<beans profile="自定义环境名">来表示
(3)激活profile
判断激活状态:spring.profiles.active和spring.profiles.default属性
优先级:spring.profiles.active > spring.profiles.default
设置这两个属性的方式:
- 作为DispatcherServlet的初始化参数
- 作为Web应用的上下文参数
- 作为JNDI条目
- 作为环境变量
- 作为JVM的系统属性
- 在集成测试类上,使用@ActiveProfiles注解设置
二、条件化的bean
Spring4引入了一个@Conditional注解,它可以应用到带有@Bean注解的方法上。如果给定的条件计算结果为true,就会创建这个bean;否则,这个bean会被忽略。
@Conditional(自定义Condition.class)
自定义Condition类是实现了Condition接口的类,只需提供matches()方法的实现即可。matches()方法返回true那么就会创建带有这个注解的bean;否则,不会创建这个bean。
具体 publiec boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata);中的ConditionContext 和AnnotatedTypeMetadata就不详细叙述了,待需要时查询。
三、处理自动装配的歧义性
之前的文章有提到这个自动装配的歧义性,就是指多个bean满足装配要求的时候,Spring无法清楚知道你要装配哪一个bean,会抛出NoUniqueBeanDefinitionException,这就造成了歧义性。
解决方案:
- 将一个bean设为首选(primary)的bean
- 使用限定符(qualifier)来帮助Spring将可选的bean范围缩小到只有一个bean
(1)标示首选的bean
@Primary注解可以与@Component注解组合用在组件扫描的bean上,也可以与@Bean组合在JavaConfig的bean声明中。
在XML配置中可以设置bean的primary属性为true来指明。
注意:不能在多个备选bean中设置2个及以上的primary,这样Spring会不正常工作。9
(2)限定自动装配的bean
- 基于默认的benaID作为限定符:
在需要注入的地方使用@Qualifier("想要注入的bean的ID"),bean的ID一般为首字母变为小写的类名。
注意点:如果注入的bean更改了类名,相应的默认的限定符也会更改,自动装配就会失效。 - 基于自定义的限定符:
同样使用@Qualifier注解,在备选bean上使用@Qualifier("自定义限定符号");
你也可以创建自定义的限定符注解:下面这个@Cold注解就可以代替@Qualifier("cold”)

四、bean的作用域
作用域的种类:
- 单例(Singleton):在整个应用中,只创建bean的一个实例。
- 原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
- 会话(Session):在Wen应用中,为每个会话创建一个bean实例。
- 请求(Rquest):在Web应用中,为每个请求创建一个bena实例。
单例是默认的作用域。@Scope("作用域类型"),这个注解可以更改作用域。

XML配置中则通过设置scope属性来改变作用域。

五、运行时值注入
在注入字面量的时候,通常会产生硬编码的配置。
Spring提供了两种在运行是时求值的方式:
- 属性占位符(Property placeholder)
- Spring表达式语语言(SpEL)
(1)属性占位符
使用@PropertySource和Environment

在Spring装配中,占位符的形式为使用"${...}"包装的属性名称。



(2)SpEL

SpEL表达式需要放到"#{...}"之中
展示几个简单的样例:
-
{1}
-
{9.84E4}
-
{'HELLO'}
-
{false}
-
{bean.property} bean的属性
-
{systemproperties['disc.title']} 通过systemproperties对象获取系统属性
网友评论