SpringBoot自定义注解@YamlPropertySource加载yml或者yaml文件(扩展了@PropertySource)

1:概述

SpringBoot的@PropertySource注解只支持加载 properties结尾的文件。当使用@ConfigurationProperties

注解配合@EnableConfigurationProperties注解将配置转换为JavaBean时,可能需要配合@PropertySource

注解加载指定的配置文件。所以为了支持以yml或者yaml文件,我自定义了注解@YamlPropertySource

2:实现

声明注解@YamlPropertySource

import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PropertySourceFactory;

import java.lang.annotation.*;

/**
* yaml property source and extension {@link PropertySource}
*
* @author liuenyuan
* @see org.springframework.context.annotation.PropertySource
**/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(YamlPropertySources.class)
public @interface YamlPropertySource {


   /**
    * 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.
    *

Both traditional and XML-based properties file formats are supported
    * — for example, {@code "classpath:/com/myco/app.properties"}
    * or {@code "file:/path/to/file.xml"}.
    *

Resource location wildcards (e.g. **/*.properties) are not permitted;
    * each location must evaluate to exactly one {@code .properties} resource.
    *

${...} placeholders will be resolved against any/all property sources already
    * registered with the {@code Environment}. See {@linkplain PropertySource above}
    * for examples.
    *

Each location will be added to the enclosing {@code Environment} as its own
    * property source, and in the order declared.
    */
   String[] value();

   /**
    * Indicate if failure to find the a {@link #value() property resource} should be
    * ignored.
    *

{@code true} is appropriate if the properties file is completely optional.
    * Default is {@code false}.
    *
    * @since 4.0
    */
   boolean ignoreResourceNotFound() default false;

   /**
    * A specific character encoding for the given resources, e.g. "UTF-8".
    *
    * @since 4.3
    */
   String encoding() default "";

   /**
    * Specify a custom {@link PropertySourceFactory}, if any.
    *

By default, a default factory for standard resource files will be used.
    *
    * @see org.springframework.core.io.support.DefaultPropertySourceFactory
    * @see org.springframework.core.io.support.ResourcePropertySource
    * @since 4.3
    */
   Classextends PropertySourceFactory> factory() default YamlPropertySourceFactory.class;
}


/**
* @author liuenyuan
* @see YamlPropertySource
**/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface YamlPropertySources {

   YamlPropertySource[] 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 YamlPropertySource} bean post processor.this class convert the yml or yaml file {@link YamlPropertySource#value()} to {@link PropertiesPropertySource},and add the property source
* named {@link YamlPropertySource#name()} into {@link Environment}.When you use this annotation,you
* must for follow example:
*
{@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;
* }}

*
* @author liuenyuan
* @date 2019/6/16 20:13
* @describe
* @see YamlPropertySource
* @see InstantiationAwareBeanPostProcessorAdapter
* @see EnvironmentAware
* @see ResourceLoaderAware
*/
@Slf4j
@Configuration(value = YamlPropertySourceAnnotationPostProcessor.BEAN_NAME)
@Order(Ordered.HIGHEST_PRECEDENCE)
public class YamlPropertySourceAnnotationPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements EnvironmentAware, ResourceLoaderAware {

   public final static String BEAN_NAME = "yamlPropertySourceAnnotationPostProcessor";

   private Environment environment;

   private ResourceLoader resourceLoader;

   private final List<String> propertySourceNames = new ArrayList<>();

   private static final PropertySourceFactory DEFAULT_PROPERTY_SOURCE_FACTORY = new YamlPropertySourceFactory();

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

转载于:https://www.cnblogs.com/liuenyuan1996/p/11033080.html

你可能感兴趣的:(SpringBoot自定义注解@YamlPropertySource加载yml或者yaml文件(扩展了@PropertySource))