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 使用@Value进行注解
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 }
属性文件 app.propertites
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运算符<难点>