Spring-注入外部值


 Spring注入需要初始化,但前面均使用硬編碼注入,如:

JavaConfig配置:

 1 package soundSystem;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * CompactDisc接口的實現類,此類中定義了CD的名字和作者以及打印相關信息的方法
 7  * @author yan
 8  */
 9 @Component("compactd")//用於掃描來動態生成bean
10 public class SgtPeppers implements CompactDisc{
11 
12     private String title="K歌之王";
13     private String artist="陳奕迅";
14     @Override
15     public void cdInfo() {
16         System.out.print("This CD's title:"+title+";artist:"+artist);
17     }
18 
19 }

xml配置(需要實現setter方法):

1     <bean id="cd" class="soundSystem.SgtPeppers">
2         <property name="title" value="L.O.V.E"></property>
3         <property name="artist" value="May Day"></property>
4     </bean>

Spring允許注入外部值,這樣不用受到硬編碼的限制:

--JavaConfig(顯式bean)

主要是在配置類中實現:

1.在配置類類名上方添加注解@PropertySource("classpath:/sp.properties"),參數為文件全路徑名,properties文件是專門用來存放k-v值對的;

2.在配置類中定義Environment env,並添加@AutoWired注解;

3.在定義bean的方法中使用env.getProperty()方法配置文件(*.properties)中的值來賦給bean作為參數。

 1 package com.spring.config;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.context.annotation.Bean;
 5 import org.springframework.context.annotation.ComponentScan;
 6 import org.springframework.context.annotation.Configuration;
 7 import org.springframework.context.annotation.PropertySource;
 8 import org.springframework.core.env.Environment;
 9 
10 import com.spring.custom.Person;
11 
12 @Configuration("com.spring.custom")
13 @ComponentScan(basePackages={"com.spring"})
14 @PropertySource("classpath:/sp.properties")
15 public class CreatureSpingConfig {
16     @Autowired
17     Environment env;
18     @Bean
19     public Person person(){
20         return new Person(env.getProperty("name"), env.getProperty("age",Integer.class), env.getProperty("sex"));
21     }
22 }

這樣就實現了從外部文件注入的目標了。

注:getProperty("key值")返回的是String類型,但並不是所有參數都是String類型,所以這個方法有幾個重載形式

解釋如下:

 1 public interface PropertyResolver {  
 2   
 3     //是否包含某個屬性  
 4     boolean containsProperty(String key);  
 5    
 6         //獲取屬性值 如果找不到返回null   
 7     String getProperty(String key);  
 8        
 9         //獲取屬性值,如果找不到返回默認值        
10     String getProperty(String key, String defaultValue);  
11     
12         //獲取指定類型的屬性值,找不到返回null  
13     <T> T getProperty(String key, Class<T> targetType);  
14   
15         //獲取指定類型的屬性值,找不到返回默認值  
16     <T> T getProperty(String key, Class<T> targetType, T defaultValue);  
17   
18          //獲取屬性值為某個Class類型,找不到返回null,如果類型不兼容將拋出ConversionException  
19     <T> Class<T> getPropertyAsClass(String key, Class<T> targetType);  
20   
21         //獲取屬性值,找不到拋出異常IllegalStateException  
22     String getRequiredProperty(String key) throws IllegalStateException;  
23   
24         //獲取指定類型的屬性值,找不到拋出異常IllegalStateException         
25     <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;  
26   
27         //替換文本中的占位符(${key})到屬性值,找不到不解析  
28     String resolvePlaceholders(String text);  
29   
30         //替換文本中的占位符(${key})到屬性值,找不到拋出異常IllegalArgumentException  
31     String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;  
32   
33 } 

這里列舉的是PropertyResolver接口中定義的方法,是因為Environment繼承了這個接口,上例中我們使用了第7行和第13行的getProperty的兩種重載的形式,當然也可是設置默認值。



 

--JavaConfig(注解生成bean)演示@Value注解使用方式

實現類:

 1 package com.spring.beans;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Value;
 5 import org.springframework.stereotype.Component;
 6 @Component//自動生成bean
 7 public class VCD implements CompactDisc{
 8     
 9 private String title;
10 private String artist;
11 private int year;
12 
13 //定義有參構造
14     @Autowired//必須寫,不寫會報錯(目前不知原因)
15     public VCD(@Value("${title}")String title, @Value("${artist}")String artist,@Value("${year}")int year) {
16     super();
17     this.title = title;
18     this.artist = artist;
19     this.year=year;}
20     @Override
21     public void play() {
22         System.out.println("Playing CD's title is"+title+",the artist is"+artist+",the year is"+year);
23         }
24     }

 配置類:

 1 package com.spring.config;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Configurable;
 5 import org.springframework.context.annotation.Bean;
 6 import org.springframework.context.annotation.ComponentScan;
 7 import org.springframework.context.annotation.Configuration;
 8 //import org.springframework.context.annotation.ImportResource;
 9 import org.springframework.context.annotation.PropertySource;
10 import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
11 import org.springframework.core.env.Environment;
12 
13 
14 @Configuration//表明這是一個Spring的配置類
15 @ComponentScan(value="com.spring")//表示需要掃描的包,因為演示所用為顯式bean,所以其實這里沒必要添加此注解
16 @PropertySource(value="classpath:propertiesSource.properties")
17 //@ImportResource("classpath:spring.xml")//引入XML配置文件
18 public class SpringConfig {
19     /**
20      * 因為采用混合配置,故注釋掉重復bean及無用變量
21      */
22     @Autowired 
23     private Environment e;
24     
25     @Bean//要使用@Value注解需要添加此bean
26     public static PropertySourcesPlaceholderConfigurer pc(){
27         return new PropertySourcesPlaceholderConfigurer();
28     }
29 }

配置文件:

title=L.O.V.E
artist=May Day
year=2006

注:

  1. 要使用@Value需要添加PropertySourcesPlaceholderConfigurer類的bean;
  2. 需要在使用@Value處添加@AutoWired注解,否則會出錯。


 

 --XML(顯式bean)

此處使用混合配置,以CD為例。

配置類:

 1 package com.spring.config;
 2 
 3 //import org.springframework.beans.factory.annotation.Autowired;
 4 //import org.springframework.beans.factory.annotation.Configurable;
 5 //import org.springframework.context.annotation.Bean;
 6 import org.springframework.context.annotation.ComponentScan;
 7 import org.springframework.context.annotation.Configuration;
 8 import org.springframework.context.annotation.ImportResource;
 9 //import org.springframework.context.annotation.PropertySource;
10 //import org.springframework.core.env.Environment;
11 
12 
13 @Configuration//表明這是一個Spring的配置類
14 @ComponentScan(value="com.spring")//表示需要掃描的包,因為演示所用為顯式bean,所以其實這里沒必要添加此注解
15 //@PropertySource(value="classpath:propertiesSource.properties")
16 @ImportResource("classpath:spring.xml")//引入XML配置文件
17 public class SpringConfig {
18     /**
19      * 因為采用混合配置,故注釋掉重復bean及無用變量
20      */
21 //    @Autowired 
22 //    private Environment e;
23     
24 //    @Bean
25 //    public CompactDisc cd(){
26 //        return new VCD(e.getProperty("title"),e.getProperty("artist"));
27 //    }
28 }

 

實現類:

 1 package com.spring.beans;
 2 public class VCD implements CompactDisc{
 3     
 4 private String title;
 5 private String artist;
 6 private int year;
 7 //定義有參構造
 8     public VCD(String title, String artist,int year) {
 9     super();
10     this.title = title;
11     this.artist = artist;
12     this.year=year;
13     System.out.println("Playing CD's title is"+this.title+",the artist is"+this.artist+",the year is"+this.year);}
14     @Override
15     public void play() {}
16 }

 

在XML中:

<?xml version="1.0" encoding="UTF-8"?>
 <beans
      xmlns="http://www.springframework.org/schema/beans"
      xmlns:c="http://www.springframework.org/schema/c"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context.xsd
     ">
     <context:property-placeholder location="classpath:propertiesSource.properties"/>
     <bean id="cd" class="com.spring.beans.VCD" c:_0="${title}" c:_1="${artist}" c:_2="${year}">
     </bean>
 </beans>

 

配置文件中:

title=L.O.V.E
artist=May Day
year=2006

 

這樣便可以實現從外部注入屬性值了。

注意:

  1. 在XML配置中,要添加<context:property-placeholder/>標簽,其屬性location的值便為配置文件的路徑,這與JavaConfig中的@PropertySource起同樣的作用;
  2. 從例子中可以看出,構造器注入,可以使用c-命名空間來設置初始值,格式如:c:_index,index為構造器中參數的索引值,從0開始。而<context:property-placeholder/>標簽是專門用來匹配屬性占位符的,缺少此標簽則不起作用。

2016-10-25 21:20:52

資料參考:

  1. Environment用法:http://blog.csdn.net/hdngbj/article/details/18003001#
  2. 混合配置用法:http://www.cnblogs.com/yw0219/p/5989865.html 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM