3.5.1 注入外部的值
在 Spring 中,处理外部值的最简单方式就是声明属性源并通过 Spring 的 Environment 来检索属性。例如,以下程序展现了一个基本的 Spring 配置类,它使用外部的属性来装配 BlankDisc bean。
在本例中,@PropertySource 引用了类路径中一个名为 app.properties 的文件。它大致会如下所示:
这个属性文件会加载到 Spring 的 Environment 中,稍后可以从这里检索属性。同时,在 disc() 方法中,会创建一个新的 BlankDisc,它的构造器参数是从属性文件中获取的,而这是通过调用 getProperty() 实现的。
深入学习 Spring 的 Environment 当我们去了解 Environment 的时候会发现,上述程序所示的 getProperty() 方法并不是获取属性值的唯一方 法,getProperty() 方法有四个重载的变种形式:
String getProperty(String key)
String getProperty(String key, String defualtValue)
T getProperty(String key, Class<T> type)
T getProperty(String key, Class<T> type, T defaultValue)
前两种形式的 getProperty() 方法都会返回 String 类型的值。我们已经在上述程序中看到了如何使用第一种 getProperty()方法。但是,你可以稍微对 @Bean 方法进行一下修改,这样在指定属性不存在的时候,会使用一个默认值:
剩下的两种 getProperty() 方法与前面的两种非常类似,但是它们不会将所有的值都视为 String 类型。例如,假设你想要获取的值所代表的含义是连接池中所维持的连接数量。如果我们从属性文件中得到 的是一个 String 类型的值,那么在使用之前还需要将其转换为 Integer 类型。但是,如果使用重载形式的 getProperty() 的话,就能非常便利地解决这个问题:
Environment 还提供了几个与属性相关的方法,如果你在使用 getProperty() 方法的时候没有指定默认值,并且这个属性没有定义的话,获取到的值是 null。如果你希望这个属性必须要定义,那么可以使用 getRequiredProperty() 方法,如下所示:
在这里,如果 disc.title 或 disc.artist 属性没有定义的话,将会抛出 IllegalStateException 异常。
如果想检查一下某个属性是否存在的话,那么可以调用 Environment 的 containsProperty() 方法:
最后,如果想将属性解析为类的话,可以使用 getPropertyAsClass() 方法:
除了属性相关的功能以外,Environment 还提供了一些方法来检查哪些 profile 处于激活状态:
String[] getActiveProfiles():返回激活 profile 名称的数组;
String[] getDefaultProfiles():返回默认 profile 名称的数组;
boolean acceptsProfiles(String... profiles):如果 environment 支持给定 profile 的话,就返回true。
直接从 Environment 中检索属性是非常方便的,尤其是在 Java 配置中装配 bean 的时候。但是,Spring 也提供了通过占位符装配属性的方法,这些占位符的值会来源于一个属性源。
解析属性占位符
Spring 一直支持将属性定义到外部的属性的文件中,并使用占位符值将其插入到 Spring bean 中。在 Spring 装配中,占位符的形式为使用 ${ ... }
包装的属性名称。作为样例,我们可以在 XML 中按照如下的 方式解析 BlankDisc 构造器参数:
可以看到,title 构造器参数所给定的值是从一个属性中解析得到的,这个属性的名称为 disc.title。artist 参数装配的是名为 disc.artist 的属性值。按照这种方式,XML 配置没有使用任何硬编码的值,它的值是从配置文件以外的一个源中解析得到的。(我们稍后会讨论这些属性是如何解析的。)
如果我们依赖于组件扫描和自动装配来创建和初始化应用组件的话,那么就没有指定占位符的配置文件或类了。在这种情况下,我们可以使用 @Value 注解,它的使用方式与 @Autowired 注解非常相似。比如,在 BlankDisc 类中,构造器可以改成如下所示:
为了使用占位符,我们必须要配置一 个 PropertyPlaceholderConfigurer bean 或 PropertySourcesPlaceholderConfigurer bean。从 Spring 3.1 开始,推荐使用 PropertySourcesPlaceholderConfigurer,因为它能够基于 Spring Environment 及其属性源来解析占位符。
如下的 @Bean 方法在 Java 中配置了 PropertySourcesPlaceholderConfigurer:
如果你想使用 XML 配置的话,Spring context 命名空间中的 <context:propertyplaceholder>
元素将会为你生成 PropertySourcesPlaceholderConfigurer bean:
解析外部属性能够将值的处理推迟到运行时,但是它的关注点在于根据名称解析来自于 Spring Environment 和属性源的属性。而 Spring 表达式语言提供了一种更通用的方式在运行时计算所要注入的值。
Last updated