spring · 2019-12-16 0

springboot 使用 @PropertySource 加载外部 properties 和 yml

1.创建 springboot 项目

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.2</version>
    <relativePath/>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.26</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

2.配置文件

application.yml

server:
  port: 9090

person1.properties

person1.name=迪丽热巴
person1.age=27

person2.yml

person2:
  name: 迪丽热巴
  age: 27

3.配置类

@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "person1")
public class Person1Property {

    private String name;

    private Integer age;
}
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "person2")
public class Person2Property {

    private String name;

    private Integer age;
}

4.加载配置文件

@PropertySource 默认只能加载 properties 文件,这里实现可以加载 yml 的 factory

@Configuration(proxyBeanMethods = false)
@PropertySource(value = {"classpath:/person1.properties"}, encoding = "utf-8")
public class Person1PropertySource {

}
@Configuration(proxyBeanMethods = false)
@PropertySource(value = {"classpath:/person2.yml"}, factory = YamlPropertySourceFactory.class)
public class Person2PropertySource {

}
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {

    @Override
    public org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource resource)
            throws IOException {
        String sourceName = Optional.ofNullable(name).orElse(resource.getResource().getFilename());
        if (sourceName == null) {
            return super.createPropertySource(name, resource);
        }
        if (!resource.getResource().exists()) {
            return new PropertiesPropertySource(sourceName, new Properties());
        }
        if (sourceName.endsWith(".yml") || sourceName.endsWith(".yaml")) {
            Properties propertiesFromYaml = loadYaml(resource);
            return new PropertiesPropertySource(sourceName, propertiesFromYaml);
        }
        return super.createPropertySource(name, resource);
    }

    private Properties loadYaml(EncodedResource resource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }
}

5.测试

@Component
public class MyRunner implements ApplicationRunner {

    @Autowired
    private Environment environment;

    @Autowired
    private Person1Property person1Property;

    @Autowired
    private Person2Property person2Property;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(environment.getProperty("server.port"));
        System.out.println(String.format("%s %s", environment.getProperty("person1.name"), environment.getProperty("person1.age")));
        System.out.println(String.format("%s %s", environment.getProperty("person2.name"), environment.getProperty("person2.age")));
        System.out.println(String.format("%s %s", person1Property.getName(), person1Property.getAge()));
        System.out.println(String.format("%s %s", person2Property.getName(), person2Property.getAge()));
    }
}
@SpringBootApplication
public class Boot {

    public static void main(String[] args) {
        SpringApplication.run(Boot.class, args);
    }
}

6.结果

9090
迪丽热巴 27
迪丽热巴 27
迪丽热巴 27
迪丽热巴 27