SpringBoot自定義註解@YmlPropertySource載入yml或者yaml檔案

海淵發表於2019-06-16

1:概述

SpringBoot的@PropertySource註解只支援載入 properties結尾的檔案。當使用@ConfigurationProperties

註解配合@EnableConfigurationProperties註解將配置轉換為JavaBean時,可能需要配合@PropertySource

註解載入指定的配置檔案。所以為了支援以yml或者yaml檔案,我自定義了註解@YmlPropertySource

2:實現

宣告註解@YmlPropertySource

/**
* 類描述: load yml or yaml file into {@link org.springframework.core.env.Environment}
*
* @author liuenyuan
* @date 2019/6/16 20:12
* @describe
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface YmlPropertySource {

   /**
    * Indicate the name of this property source. If omitted, a name will
    * be generated based on the description of the underlying resource.
    *
    * @see org.springframework.core.env.PropertySource#getName()
    * @see org.springframework.core.io.Resource#getDescription()
    */
   String name() default "";

   /**
    * Indicate the resource location(s) of the properties file to be loaded.
    * <p>Both traditional and XML-based properties file formats are supported
    * &mdash; for example, {@code "classpath:/com/myco/app.yml|yaml"}
    * <p>Resource location wildcards (e.g. *&#42;/*.yml|yaml) are not permitted;
    * each location must evaluate to exactly one {@code .properties} resource.
    * <p>${...} placeholders will be resolved against any/all property sources already
    * registered with the {@code Environment}. See {@linkplain YmlPropertySource above}
    * for examples.
    * <p>Each location will be added to the enclosing {@code Environment} as its own
    * property source, and in the order declared.
    */
   String[] value();
}

具體實現如下


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.*;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.*;

/**
* 類描述: {@link YmlPropertySource} bean post processor.this class convert the yml or yaml file
* {@link YmlPropertySource#value()} to {@link PropertiesPropertySource},and add the property source
* named {@link YmlPropertySource#name()} into {@link Environment}.When you use this annotation,you
* must for follow example:
* <pre>{@code
* @link @ConfigurationProperties(prefix = "person")
* @link @YmlPropertySource(value = {"classpath:/hello.yml"}, name = "hello")
* @link @Data
* public class PersonProperties {
*
* private String name;
*
* private Integer age;
*
* private String school;
* }}</pre>
*
* @author liuenyuan
* @date 2019/6/16 20:13
* @describe
* @see YmlPropertySource
* @see InstantiationAwareBeanPostProcessorAdapter
* @see EnvironmentAware
* @see ResourceLoaderAware
*/
@Slf4j
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class YmlPropertySourceAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements EnvironmentAware, ResourceLoaderAware {

   private Environment environment;

   private ResourceLoader resourceLoader;

   @Override
   public void setEnvironment(Environment environment) {
       Assert.isInstanceOf(ConfigurableEnvironment.class, environment, "environment must be instance of ConfigurableEnvironment.");
       this.environment = environment;
  }

   @Override
   public void setResourceLoader(ResourceLoader resourceLoader) {
       this.resourceLoader = resourceLoader;
  }


   @Override
   public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
       

相關文章