Spring实战(第四版)读书笔记——第三章 高级装配(一)

如果有人看的话,劳烦各位不吝指出不足之处,谢谢!

3.1 环境与 profile

3.1.1 配置 profile bean

在 3.1 版本中, Spring 引入了 bean profile 的功能。要使用 profile ,你首先要将所有不同的 bean 定义整理到一个或多个 profile 之中,在将应用部署到每个环境时,要确保对应的 profile 处于激活( active )的状态。

在 Java 配置中,可以使用 @Profile 注解指定某个 bean 属于哪一个 profile 。@Profile 注解应用在类级别上,它会告诉 Spring 这个配置类中的 bean 只有在 dev profile 激活时才会创建。如果 dev profile 没有激活的话,那么带有 @Bean 注解的方法都会被忽略掉。

在 Spring 3.1 中,只能在类级别上使用 @Profile 注解。不过,从 Spring 3.2 开始,你也可以在方法级别上使用 @Profile 注解,与 @Bean 注解一同使用。

我们也可以通过 <beans> 元素的 profile 属性,在 XML 中配置 profile bean 。例如,为了在 XML 中定义适用于开发阶段的嵌入式数据库 DataSourcebean ,我们可以创建如下所示的 XML 文件:


还可以在根 <beans> 元素中嵌套定义 <beans> 元素,而不是为每个环境都创建一个 profile XML 文件。这能够将所有的 profile bean 定义放到同一个 XML 文件中,如下所示:


3.1.2 激活 profile

Spring 在确定哪个 profile 处于激活状态时,需要依赖两个独立的属性: spring.profiles.active 和 spring.profiles.default 。如果设置了 spring.profiles.active 属性的话,那么它的值就会用来确定哪个 profile 是激活的。但如果没有设置 spring.profiles.active 属性的话,那 Spring 将会查找 spring.profiles.default 的值。

有多种方式来设置这两个属性:

  • 作为 DispatcherServlet 的初始化参数;
  • 作为 Web 应用的上下文参数;
  • 作为 JNDI 条目;
  • 作为环境变量;
  • 作为 JVM 的系统属性;
  • 在集成测试类上,使用 @ActiveProfiles 注解设置。

Spring 提供了 @ActiveProfiles 注解,我们可以使用它来指定运行测试时要激活哪个 profile 。在集成测试时,通常想要激活的是开发环境的profile 。例如,下面的测试类片段展现了使用 @ActiveProfiles 激活 dev profile :


3.2 条件化的bean

Spring 4 引入了一个新的 @Conditional 注解,它可以用到带有 @Bean 注解的方法上。如果给定的条件计算结果为 true ,就会创建这个 bean ,否则的话,这个 bean 会被忽略。

假设有一个名为 MagicBean 的类,我们希望只有设置了 magic 环境属性的时候, Spring 才会实例化这个类。如果环境中没有这个属性,那么 MagicBean 将会被忽略。在程序清单 3.4 所展现的配置中,使用 @Conditional 注解条件化地配置了 MagicBean 。


可以看到, @Conditional 中给定了一个 Class ,它指明了条件 —— 在本例中,也就是 MagicExistsCondition 。 @Conditional 将会通过 Condition 接口进行条件对比:


设置给 @Conditional 的类可以是任意实现了 Condition 接口的类型。可以看出来,这个接口实现起来很简单直接,只需提供 matches() 方法的实现即可。如果 matches() 方法返回 true ,那么就会创建带有 @Conditional 注解的 bean 。如果 matches() 方法返回 false ,将不会创建这些 bean 。

在本例中,我们需要创建 Condition 的实现并根据环境中是否存在 magic 属性来做出决策。这是完成该功能的 Condition 实现类:


 matches() 方法会得到 ConditionContext 和 AnnotatedTypeMetadata 对象用来做出决策。

通过 ConditionContext ,我们可以做到如下几点:

  • 借助 getRegistry() 返回的 BeanDefinitionRegistry 检查 bean 定义;
  • 借助 getBeanFactory() 返回的 ConfigurableListableBeanFactory 检查 bean 是否存在,甚至探查 bean 的属性;
  • 借助 getEnvironment() 返回的 Environment 检查环境变量是否存在以及它的值是什么;
  • 读取并探查 getResourceLoader() 返回的 ResourceLoader 所加载的资源;
  • AnnotatedTypeMetadata 则能够让我们检查带有 @Bean 注解的方法上还有什么其他的注解。像 ConditionContext 一
    样, AnnotatedTypeMetadata 也是一个接口。它如下所示:借助 getClassLoader() 返回的 ClassLoader 加载并检查类是否存在。
AnnotatedTypeMetadata 则能够让我们检查带有 @Bean 注解的方法上还有什么其他的注解。像 ConditionContext 一

样, AnnotatedTypeMetadata 也是一个接口。它如下所示:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值