1. 将一个值注入到bean的属性或者 构造器参数中,而这个值是在运行的时候确定的。Spring提 供了两种在运行时求值的方式:
- 属性占位符(Property placeholder)。
- Spring表达式语言(SpEL)。
2. 注入外部的值
在Spring中,处理外部值的最简单方式就是声明属性源并通过Spring 的Environment来检索属性。
配置文件:
1 package soundsystem;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration;
6 import org.springframework.context.annotation.PropertySource;
7 import org.springframework.core.env.Environment;
8
9 @Configuration
10 @PropertySource("classpath:soundsystem/app.properties")
11 public class CDPlayerEXpressConfig {
12 @Autowired
13 Environment env;
14
15 @Bean
16 public BlankDisc disc() {
17 return new BlankDisc(env.getProperty("disc.title"), env.getProperty("disc.artist"));
18 }
19 }
属性文件:
app.propertites
1 disc.title=Sgt. Peppers Lonely Hearts Club Band
2 disc.artist=The Beatles
结果:
3. Spring的Environment
<1>getProperty()方法有四个重载的变种形式:
在指定属性不存 在的时候可以使用第二个方法进行参数传递
剩下的两种getProperty()方法与前面的两种非常类似,但是它们 不会将所有的值都视为String类型。例如,假设你想要获取的值所代 表的含义是连接池中所维持的连接数量。如果我们从属性文件中得到 的是一个String类型的值,那么在使用之前还需要将其转换为Integer类 型。但是,如果使用重载形式的getProperty()的话,就能非常便 利地解决这个问题:
<2>Environment还提供了几个与属性相关的方法,如果你在使 用getProperty()方法的时候没有指定默认 值,并且这个属性没有 定义的话,获取到的值是null。如果你希望这个属性必须要定义,那 么可以使用 getRequiredProperty()方法,如下所示:
如果disc.title或disc.artist属性没有定义的话,将 会抛出IllegalStateException异常。
<3>如果想检查一下某个属性是否存在的话,那么可以调 用Environment的containsProperty()方法:
<4>最后,如果想将属性解析为类的话,可以使 用getPropertyAsClass()方法:
4. 解析属性占位符
直接从Environment中检索属性是非常方便的,尤其是在Java配置 中装配bean的时候。但是,Spring也提供了通过占位符装配属性的方法,这些占位符的值会来源于一个属性源。
Spring一直支持将属性定义到外部的属性的文件中,并使用占位符值 将其插入到Spring bean中。在Spring装配中,占位符的形式为使用“${ ... }”包装的属性名称
<1>Java配置
CDPlayerExpressConfig.java 为了使用占位符,我们必须要配置一 个PropertySourcesPlaceholderConfigurer bean,因为它能够基于Spring Environment及其属性源来解析占位符
1 package soundsystem;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.context.annotation.Bean;
5 import org.springframework.context.annotation.Configuration;
6 import org.springframework.context.annotation.PropertySource;
7 import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
8 import org.springframework.core.env.Environment;
9
10 @Configuration
11 @PropertySource("classpath:soundsystem/app.properties")
12 public class CDPlayerEXpressConfig {
13 @Autowired
14 Environment env;
15
16 @Bean
17 public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
18 return new PropertySourcesPlaceholderConfigurer();
19 }
20
21 @Bean
22 public BlankDisc disc() {
23 return new BlankDisc(env.getProperty("disc.title"), env.getProperty("disc.artist"));
24 }
25 }
BlankDisc.java
1 package soundsystem;
2
3 import org.springframework.beans.factory.annotation.Value;
4
5 public class BlankDisc implements CompactDiscs {
6 @Value("${disc.title}")
7 String titles;
8 @Value("${disc.artist}")
9 String artists;
10 private String title;
11 private String artist;
12
13 public BlankDisc(String title, String artist) {
14 this.title = title;
15 this.artist = artist;
16 }
17
18 @Override
19 public void play() {
20 // TODO Auto-generated method stub
21 System.out.println("解析属性占位符");
22 System.out.println("Playing " + titles + " by " + artists);
23 System.out.println("直接获取");
24 System.out.println("Playing " + title + " by " + artist);
25 }
26
27 }
CDPlayerTest.java
1 package soundsystem;
2
3 import org.junit.Test;
4 import org.junit.runner.RunWith;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.test.context.ContextConfiguration;
7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
8
9 @RunWith(SpringJUnit4ClassRunner.class)
10 @ContextConfiguration(classes = soundsystem.CDPlayerEXpressConfig.class)
11 public class CDPlayerTest {
12 @Autowired
13 private CompactDiscs cd;
14
15 @Test
16 public void test() {
17 cd.play();
18 }
19 }
属性文件
1 disc.title=111111111111111111
2 disc.artist=2222222222222222222222
结果
<2>XML配置
External.xml Spring context命名空间中的 <context:propertyplaceholder>元素将会为你生成PropertySourcesPlaceholderConfigurer bean
使用c命名空间必须先引入,即 xmlns:c="http://www.springframework.org/schema/c"
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xmlns:aop="http://www.springframework.org/schema/aop"
5 xmlns:tx="http://www.springframework.org/schema/tx"
6 xmlns:context="http://www.springframework.org/schema/context"
7 xmlns:c="http://www.springframework.org/schema/c"
8 xsi:schemaLocation="
9 http://www.springframework.org/schema/beans
10 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
11 http://www.springframework.org/schema/aop
12 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
13 http://www.springframework.org/schema/tx
14 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
15 http://www.springframework.org/schema/context
16 http://www.springframework.org/schema/context/spring-context-3.0.xsd">
17 <context:property-placeholder location="soundsystem2/app.properties"/>
18 <bean id="bld"
19 class="soundsystem2.BlankDisc"
20 c:title="${disc.title}"
21 c:artist="${disc.artist}"
22 >
23 </bean>
24 </beans>
BlankDisc.java
1 package soundsystem2;
2
3 public class BlankDisc implements CompactDiscs {
4 private String title;
5 private String artist;
6
7 public BlankDisc(String title, String artist) {
8 this.title = title;
9 this.artist = artist;
10 }
11
12 @Override
13 public void play() {
14 // TODO Auto-generated method stub
15 System.out.println("获取");
16 System.out.println("Playing " + title + " by " + artist);
17 }
18
19 }
CDPlayerTest.java
1 package soundsystem2;
2
3 import org.junit.Test;
4 import org.junit.runner.RunWith;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.test.context.ContextConfiguration;
7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
8
9 @RunWith(SpringJUnit4ClassRunner.class)
10 @ContextConfiguration("classpath:External.xml")
11 public class CDPlayerTest {
12 @Autowired
13 private CompactDiscs cd;
14
15 @Test
16 public void test() {
17 cd.play();
18 }
19 }
属性文件 app.propertites
1 disc.title=ABC
2 disc.artist=CBA
结果
5. 使用Spring表达式语言进行装配 <重点>
解析外部属性能够将值的处理推迟到运行时,但是它的关注点在于根 据名称解析来自于Spring Environment和属性源的属性。而Spring表 达式语言提供了一种更通用的方式在运行时计算所要注入的值。
Spring表达式语言(Spring Expression Language, SpEL),它能够以一种强大和简洁的方式将值装配到bean属性和构造 器参数中,在这个过程中所使用的表达式会在运行时计算得到值。SpEL表达式 要放到“#{ ... }”之中
在XML文件中对bean进行配置,然后根据bean的ID就可以实现对bean的操作,即引用bean、属性和方法
#{bean的ID} 获取对应ID的bean对象
#{bean的ID.属性} 获取对应ID的bean的属性
6. SpEL运算符<难点>