淺析PropertySource 基本使用

一、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

歡迎關注:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章