一、PropertySource 簡介
org.springframework.context.annotation.PropertySource 是一個注解,可以標記在類上、接口上、枚舉上,在運行時起作用。而@Repeatable(value = PropertySources.class) 表示在PropertySources 中此注解時可以重復使用的。如下:
二、@PropertySource與Environment讀取配置文件
此注解@PropertySource 為Spring 中的 Environment提供方便和聲明機制,通常與Configuration一起搭配使用。
- 新建一個maven 項目,添加pom.xml 依賴:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.spring.propertysource</groupId>
<artifactId>spring-propertysource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-propertysource</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring.version>4.3.13.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
一般把版本名稱統一定義在
標簽中,便於統一管理,如上可以通過 ${…}
來獲取指定版本。
- 定義一個application.properties 來寫入如下配置
com.spring.name=liuXuan
com.spring.age=18
- 新建一個TestBean,定義幾個屬性
public class TestBean {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "TestBean{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 新建一個main class ,用來演示@PropertySource 的使用
@Configuration
@PropertySource(value = "classpath:application.properties",ignoreResourceNotFound = false)
public class SpringPropertysourceApplication {
@Resource
Environment environment;
@Bean
public TestBean testBean(){
TestBean testBean = new TestBean();
// 讀取application.properties中的name
testBean.setName(environment.getProperty("com.spring.name"));
// 讀取application.properties中的age
testBean.setAge(Integer.valueOf(environment.getProperty("com.spring.age")));
System.out.println("testBean = " + testBean);
return testBean;
}
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringPropertysourceApplication.class);
TestBean testBean = (TestBean)applicationContext.getBean("testBean");
}
}
輸出:
testBean = TestBean{name='liuXuan', age=18}
Refreshing the spring context
@Configuration : 相當於
標簽,注意不是 ,一個配置類可以有多個bean,但是只能有一個 @PropertySource: 用於引入外部屬性配置,和Environment 配合一起使用。其中ignoreResourceNotFound 表示沒有找到文件是否會報錯,默認為false,就是會報錯,一般開發情況應該使用默認值,設置為true相當於生吞異常,增加排查問題的復雜性.
引入PropertySource,注入Environment,然后就能用environment 獲取配置文件中的value值。
三、@PropertySource與@Value讀取配置文件
@Value 基本使用
我們以DB的配置文件為例,來看一下如何使用@Value
讀取配置文件
- 首先新建一個DBConnection,具體代碼如下:
// 組件bean
@Component
@PropertySource("classpath:db.properties")
public class DBConnection {
@Value("${DB_DRIVER_CLASS}")
private String driverClass;
@Value("${DB_URL}")
private String dbUrl;
@Value("${DB_USERNAME}")
private String userName;
@Value("${DB_PASSWORD}")
private String password;
public DBConnection(){}
public void printDBConfigs(){
System.out.println("Db Driver Class = " + driverClass);
System.out.println("Db url = " + dbUrl);
System.out.println("Db username = " + userName);
System.out.println("Db password = " + password);
}
}
類上加入@Component 表示這是一個組件bean,需要被spring進行管理,@PropertySource 用於獲取類路徑下的db.properties 配置文件,@Value用於獲取properties中的key 對應的value值,printDBConfigs方法打印出來對應的值。
- 新建一個db.properties,具體文件如下
#MYSQL Database Configurations
DB_DRIVER_CLASS=com.mysql.jdbc.Driver
DB_URL=jdbc:mysql://localhost:3306/test
DB_USERNAME=cxuan
DB_PASSWORD=111111
APP_NAME=PropertySourceExample
這是一個MYSQL連接數據庫驅動的配置文件。
- 新建一個SpringMainClass,用於測試DBConection中是否能夠獲取到@Value的值
public class SpringMainClass {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 注解掃描,和@ComponentScan 和 基於XML的配置<context:component-scan base-package>相同
context.scan("com.spring.propertysource.app");
// 刷新上下文環境
context.refresh();
System.out.println("Refreshing the spring context");
// 獲取DBConnection這個Bean,調用其中的方法
DBConnection dbConnection = context.getBean(DBConnection.class);
dbConnection.printDBConfigs();
// 關閉容器(可以省略,容器可以自動關閉)
context.close();
}
}
輸出:
Refreshing the spring context
Db Driver Class = com.mysql.jdbc.Driver
Db url = jdbc:mysql://localhost:3306/test
Db username = cxuan
Db password = 111111
@Value 高級用法
在實現了上述的例子之后,我們再來看一下@Value 的高級用法:
- @Value 可以直接為字段賦值,例如:
@Value("cxuan")
String name;
@Value(10)
Integer age;
@Value("${APP_NAME_NOT_FOUND:Default}")
private String defaultAppName;
- @Value 可以直接獲取系統屬性,例如:
@Value("${java.home}")
// @Value("#{systemProperties['java.home']}") SPEL 表達式
String javaHome;
@Value("${HOME}")
String dir;
- @Value 可以注解在方法和參數上
@Value("Test") // 可以直接使用Test 進行單元測試
public void printValues(String s, @Value("another variable") String v) {
...
}
修改DBConnection后的代碼如下:
public class DBConnection {
@Value("${DB_DRIVER_CLASS}")
private String driverClass;
@Value("${DB_URL}")
private String dbUrl;
@Value("${DB_USERNAME}")
private String userName;
@Value("${DB_PASSWORD}")
private String password;
public DBConnection(){}
public void printDBConfigs(){
System.out.println("Db Driver Class = " + driverClass);
System.out.println("Db url = " + dbUrl);
System.out.println("Db username = " + userName);
System.out.println("Db password = " + password);
}
}
在com.spring.propertysource.app 下 新增DBConfiguration,作用是配置管理類,管理DBConnection,並讀取配置文件,代碼如下:
@Configuration
@PropertySources({
@PropertySource("classpath:db.properties"),
@PropertySource(value = "classpath:root.properties", ignoreResourceNotFound = true)
})
public class DBConfiguration {
@Value("Default DBConfiguration")
private String defaultName;
@Value("true")
private boolean defaultBoolean;
@Value("10")
private int defaultInt;
@Value("${APP_NAME_NOT_FOUND:Default}")
private String defaultAppName;
@Value("#{systemProperties['java.home']}")
// @Value("${java.home}")
private String javaHome;
@Value("${HOME}")
private String homeDir;
@Bean
public DBConnection getDBConnection() {
DBConnection dbConnection = new DBConnection();
return dbConnection;
}
@Value("Test") // 開啟測試
public void printValues(String s, @Value("another variable") String v) {
System.out.println("Input Argument 1 = " + s);
System.out.println("Input Argument 2 = " + v);
System.out.println("Home Directory = " + homeDir);
System.out.println("Default Configuration Name = " + defaultName);
System.out.println("Default App Name = " + defaultAppName);
System.out.println("Java Home = " + javaHome);
System.out.println("Home dir = " + homeDir);
System.out.println("Boolean = " + defaultBoolean);
System.out.println("Int = " + defaultInt);
}
}
使用SpringMainClass 進行測試,測試結果如下:
Input Argument 1 = Test
Input Argument 2 = another variable
Home Directory = /Users/mr.l
Default Configuration Name = Default DBConfiguration
Default App Name = Default
Java Home = /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre
Home dir = /Users/mr.l
Boolean = true
Int = 10
Refreshing the spring context
Db Driver Class = com.mysql.jdbc.Driver
Db url = jdbc:mysql://localhost:3306/test
Db username = cxuan
Db password = 111111
可以看到上述代碼並沒有顯示調用printValues 方法,默認是以單元測試的方式進行的。
四、@PropertySource 與 @Import
@Import 可以用來導入 @PropertySource 標注的類,具體代碼如下:
- 新建一個PropertySourceReadApplication 類,用於讀取配置文件並測試,具體代碼如下:
// 導入BasicPropertyWithJavaConfig類
@Import(BasicPropertyWithJavaConfig.class)
public class PropertySourceReadApplication {
@Resource
private Environment env;
@Value("${com.spring.name}")
private String name;
@Bean("context")
public PropertySourceReadApplication contextLoadInitialized(){
// 用environment 讀取配置文件
System.out.println(env.getProperty("com.spring.age"));
// 用@Value 讀取配置文件
System.out.println("name = " + name);
return null;
}
public static void main(String[] args) {
// AnnotationConnfigApplicationContext 內部會注冊Bean
new AnnotationConfigApplicationContext(PropertySourceReadApplication.class);
}
}
- 新建一個BasicPropertyWithJavaConfig 類,用於配置類並加載配置文件
@Configuration
@PropertySource(value = "classpath:application.properties")
public class BasicPropertyWithJavaConfig {
public BasicPropertyWithJavaConfig(){
super();
}
}
啟動PropertySourceReadApplication ,console能夠發現讀取到配置文件中的value值
18
name = cxuan