SpringBoot通过@PropertySource注解加载*.properties文件

319 阅读2分钟

文章参考:

关键步骤剖析:

  1. 手动注入属性类:
package com.guangdu.cheese.record.biz.anotation;

import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

/**
 * @author cheese
 * @version v1.0
 * @description
 *      手动注入 属性
 * @since 2019/8/25 10:47
 */
@Data
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@FieldDefaults(level = AccessLevel.PRIVATE)
@Component
public class ManualInjection {

    /**
     * 注入普通字符串
     */
    @Value("注入普通字符串")
    String normal;
    /**
     * 获取系统所有的属性
     */
    @Value("#{systemProperties}")
    Map<Object, Object> propertiesMap;
    /**
     * 获取系统所有的环境变量
     */
    @Value("#{systemEnvironment}")
    Map<Object, Object> envMap;
    /**
     * 获取系统java版本,使用了SpEL表达式,注入操作系统属性
     */
    @Value("#{systemProperties['java.version']}")
    String systemPropertiesName;
    /**
     * 获得随机数
     */
    @Value("#{T(java.lang.Math).random()*80}")
    double randomNumber;
    /**
     * 注入表达式结果 1 + 2的求和
     */
    @Value("#{1 + 2}")
    double sum;
    /**
     * 注入文件资源
     */
    @Value("classpath:os.yaml")
    Resource resource;
    /**
     * 注入url资源
     */
    @Value("http://www.baidu.com")
    Resource url;
    /**
     * 注入类属性
     */
    @Value("#{st.name}")
    String studentName;
    
    @Override
    public String toString() {
        return "AnnotationDemo{" +
                "normal='" + normal + '\'' +
                // ", propertiesMap=" + propertiesMap +
                // ", envMap=" + envMap +
                ", systemPropertiesName='" + systemPropertiesName + '\'' +
                ", randomNumber=" + randomNumber +
                ", sum=" + sum +
                ", resource=" + resource +
                ", url=" + url +
                ", studentName='" + studentName + '\'' +
                '}';
    }
}

对应的单元测试类为:

package com.guangdu.cheese.record.biz.anotation;

import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author cheese
 * @version v1.0
 * @description
 * @since 2019/8/25 11:19
 */
@RunWith(SpringRunner.class)
@SpringBootTest
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ManualInjectionTest {

    @Autowired
    ManualInjection manual;

    @Test
    public void contextLoads() {
        System.err.println(manual);
    }
}

输出结果为:AnnotationDemo{normal='注入普通字符串', systemPropertiesName='1.8.0_60', randomNumber=28.556780308631122, sum=3.0, resource=class path resource [os.yaml], url=URL [www.baidu.com], studentName='悟空'}

  1. 通过配置文件注入:
package com.guangdu.cheese.record.biz.anotation;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.experimental.FieldDefaults;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

/**
 * @author liujiang
 * @version v1.0
 * @description
 *      通过配置文件读取配置文件
 *
 *      需要注意一点:在通过配置文件注入属性之后,读取中文乱码;百度查之:
 *      idea中.properties文件是单独编码的,发现我没改之前是gbk的所以代码中指定了utf-8还是乱码,修改下面设置为utf-8问题解决
 *      修改属性:Editor -> File Encodings --> Properties Files(*.properties)设置编码格式为utf-8
 * @since 2019/8/25 14:30
 */
@Component
@Getter
@PropertySource(value = {"classpath:config.properties", "classpath:config_${anotherfile.configinject}.properties"}, encoding = "utf-8")
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigurationInjection {

    /**
     * config.properties
     */
    @Value("${app.name}")
    String appName;
    /**
     * config.properties
     */
    @Value("${anotherfile.configinject}")
    String inject;
    /**
     * config.properties
     */
    @Value("${book.name}")
    String bookName;
    /**
     * config_system.properties
     */
    @Value("${book.name.author}")
    String author;
    /**
     * 注入环境变量对象,存储注入的属性值
     */
    @Autowired
    Environment env;
    
    @Override
    public String toString() {
        return "PropertiesReadTest{" +
                "appName='" + appName + '\'' +
                ", inject='" + inject + '\'' +
                ", bookName='" + bookName + '\'' +
                ", author='" + author + '\'' +
                ", env=" + env +
                '}';
    }
}

单元测试如下:

package com.guangdu.cheese.record.biz.anotation;

import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author liujiang
 * @version v1.0
 * @description
 * @since 2019/8/25 14:34
 */
@RunWith(SpringRunner.class)
@SpringBootTest
@FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigurationInjectionTest {

    @Autowired
    ConfigurationInjection configura;

    @Test
    public void test() {
        System.err.println(configura.toString());
    }

}

运行结果为:PropertiesReadTest{appName='ͬ同步教育', inject='system', bookName='红楼梦', author='吴承恩', env=StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}, MapPropertySource {name='Inlined Test Properties'}, PropertiesPropertySource {name='systemProperties'}, OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}, RandomValuePropertySource {name='random'}, OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}, ResourcePropertySource {name='class path resource [config_system.properties]'}, ResourcePropertySource {name='class path resource [config.properties]'}]}}


文章中还有一些值得学习的地方,详情请参考上文链接。但也遇到了一些坑,记录下吧:
  • 读取*.properties文件中的中文时,出现乱码。之前已经设置过项目的编码格式为UTF-8,所以很疑惑。后面才知道IDEA需要对.properties文件设置单独的编码格式。截图如下:
    properties配置文件截图