精华内容
下载资源
问答
  • A.Spring从3.1版本开始增加了ConfigurableEnvironment和PropertySource: ConfigurableEnvironment Spring的ApplicationContext会包含一个Environment(实现ConfigurableEnvironment接口) ...

    1.使用spring中的知识点

    A.Spring从3.1版本开始增加了ConfigurableEnvironment和PropertySource:

    • ConfigurableEnvironment
      Spring的ApplicationContext会包含一个Environment(实现ConfigurableEnvironment接口)
      ConfigurableEnvironment自身包含了很多个PropertySource
    • PropertySource
      属性源
      可以理解为很多个Key - Value的属性配置

    需要注意的是,PropertySource之间是有优先级顺序的,如果有一个Key在多个property source中都存在,那么在前面的property source优先。

    B.Spring中的BeanFactoryPostProcessor

     在标准初始化之后修改应用程序上下文的内部bean工厂。所有的bean定义都将被加载,但是没有bean被实例化。这允许覆盖或添加属性,甚至是对迫切初始化的bean。

    也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,所以在此过成中添加上自定义的PropertySource。

     

    C.Spring中的EnvironmentAware,用于获取 ConfigurableEnvironment

        此外,不得不提一下Aware接口,它其实是一个空接口,里面不包含任何方法。它表示已感知的意思,通过这类接口可以获取指定对象,比如:

    • 通过BeanFactoryAware获取BeanFactory
    • 通过ApplicationContextAware获取ApplicationContext
    • 通过BeanNameAware获取BeanName等

     

    2.主要实现代码如下:

    1.自定义类PropertySourcesProcessor,作用:实例化之前添加自定义的PropertySource

    @Component

    public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware {

     

     

        private ConfigurableEnvironment environment;

     

     

        @Override

        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

            if (!this.environment.getPropertySources().contains("test")) {

                //PropertySource<T>中的 泛型具体类型,在该类中,获取外部参数

                ReadSettings readSettings = new ReadSettings();

                //实例化自定义的 PropertySource

                ConfigPropertySource propertySource  = new ConfigPropertySource("test",readSettings);

                //把PropertySource添加到spring environment中

                this.environment.getPropertySources().addFirst(propertySource);

            }

        }

     

     

        @Override

        public void setEnvironment(Environment environment) {

            this.environment = (ConfigurableEnvironment)environment;

        }

    }

    2.自定义类ConfigPropertySource,继承EnumerablePropertySource类,作用:重写getProperty方法,读取外部配置

     

    public class ConfigPropertySource extends EnumerablePropertySource<ReadSettings> {

     

     

        public ConfigPropertySource(String name, ReadSettings source) {

            super(name, source);

        }

     

        @Override

        public String[] getPropertyNames() {

            Set<String> keys = this.source.getKeys();

            return keys.toArray(new String[keys.size()]);

        }

     

     

        //重写 getProperty 方法,value值从 ReadSettings 中获取

        @Override

        public Object getProperty(String s) {

            return this.source.readValue(s);

        }

    }

    3.自定义类ReadSettings,作用:读取外部资源功能类

     

    public class ReadSettings {

     

     

       private Properties pro = new Properties();

     

     

        public String readValue(String name){

            try {

                //这里也可以通过HTTP请求远程读取配置文件

                pro = new Properties();

                InputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\Desktop\\222.properties"));

                pro.load(in);

                String property = pro.getProperty(name);

                return property;

            catch (IOException e) {

                e.printStackTrace();

            }

            return System.currentTimeMillis()+"";

        }

     

     

        public Set<String> getKeys(){

            Set<String> keys = new HashSet<>();

            Iterator i$ = pro.entrySet().iterator();

            while(i$.hasNext()) {

                Map.Entry<Object, Object> e = (Map.Entry)i$.next();

                keys.add(e.getKey().toString());

            }

            return keys;

        }

    }

    在使用配置文件时,直接使用@Value 注解即可。

    参考apollo配置中心,客户端启动读取远程配置文件方法

    https://ctripcorp.github.io/apollo/#/zh/design/apollo-design?id=_31-%e5%92%8cspring%e9%9b%86%e6%88%90%e7%9a%84%e5%8e%9f%e7%90%86

    展开全文
  • PropertySource:属性资源,以name/value形式存储 protected final String name; //属性名字 protected final T source; //属性资源 配合属性解析器使用的接口: public boolean containsProperty(String name) {//...

    PropertySource:属性资源,以name/value形式存储

    protected final String name; //属性名字
    protected final T source; //属性资源
    

    配合属性解析器使用的接口:

    public boolean containsProperty(String name) {//判断该资源是否含有指定名称的key
    		return (getProperty(name) != null);
    	}
    @Nullable
    public abstract Object getProperty(String name);//从资源中获取值
    

    占位资源,用于保证自己的顺序,后续通过replace换成真实资源,例如ServeltContext等:

    public static class StubPropertySource extends PropertySource<Object> {
    		public StubPropertySource(String name) {
    			super(name, new Object());
    		}
    		@Override
    		@Nullable
    		public String getProperty(String name) {
    			return null;
    		}
    	}
    

    在springframework核心包中有一个实现,可以枚举属性名字:

    public abstract class EnumerablePropertySource<T> extends PropertySource<T> {
    
    	public EnumerablePropertySource(String name, T source) {
    		super(name, source);
    	}
    	protected EnumerablePropertySource(String name) {
    		super(name);
    	}
    	@Override
    	public boolean containsProperty(String name) {
    		return ObjectUtils.containsElement(getPropertyNames(), name);
    	}
    	//枚举所有属性名字
    	public abstract String[] getPropertyNames();
    
    }
    

    EnumerablePropertySource的直接实现:

    CompositePropertySource (org.springframework.core.env)//符合型实现,有一个set持有PropertySource
    CommandLinePropertySource (org.springframework.core.env)//命令行属性资源
    MapPropertySource (org.springframework.core.env)//map型资源
    AnnotationsPropertySource (org.springframework.boot.test.autoconfigure.properties)//通过注解注入的属性资源
    

    其中MapPropertySource是使用较广的,他的实现有:

    PropertiesPropertySource (org.springframework.core.env)//通过Properties资源构建属性资源
           ResourcePropertySource (org.springframework.core.io.support)//直接通过资源路径构建属性资源
           MockPropertySource (org.springframework.mock.env)//测试使用的属性资源
    SystemEnvironmentPropertySource (org.springframework.core.env)//对系统环境转换成属性资源
    

    命令行属性资源:

    CommandLinePropertySource (org.springframework.core.env)
    		SimpleCommandLinePropertySource (org.springframework.core.env)//能够吧命令行参数封装成属性资源
    

    通过上面的源码解析,可以看到,spring的属性资源,按照不同的场景,可以自行构建自定义属性资源,从而能解析符合自己业务需求的资源,比如从某个网络位置进行资源解析,等等.

    展开全文
  • 主要介绍了Spring Boot自定义配置属性源(PropertySource),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • springboot加载自定义yml文件(@PropertySource

    springboot 加载自定义yml文件(@PropertySource)

     

    默认不能加载yml文件,需要自定义实现PropertySourceFactory接口的类进行加载

     

     

    *******************

    相关类与接口

     

    @PropertySource

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Repeatable(PropertySources.class)
    public @interface PropertySource {
     
        String[] value();    //加载文件位置
     
        String name() default "";
        boolean ignoreResourceNotFound() default false;
        String encoding() default "";
     
        Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
                            //自定义factory,默认不能加载yml文件,可自定义factory
    }
    

     

    PropertySourceFactory

    public interface PropertySourceFactory {
        PropertySource<?> createPropertySource(@Nullable String var1, EncodedResource var2) throws IOException;
    }
    

     

    DefaultPropertySourceFactory

    public class DefaultPropertySourceFactory implements PropertySourceFactory {
        public DefaultPropertySourceFactory() {
        }
    
        public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
            return name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource);
        }
    }
    

     

    ResourcePropertySource

    public class ResourcePropertySource extends PropertiesPropertySource {
        @Nullable
        private final String resourceName;
    
    
    *************
    构造函数
    
        public ResourcePropertySource(String name, EncodedResource resource) throws IOException {
        public ResourcePropertySource(EncodedResource resource) throws IOException {
        public ResourcePropertySource(String name, Resource resource) throws IOException {
        public ResourcePropertySource(Resource resource) throws IOException {
    
        public ResourcePropertySource(String name, String location, ClassLoader classLoader) throws IOException {
        public ResourcePropertySource(String location, ClassLoader classLoader) throws IOException {
        public ResourcePropertySource(String name, String location) throws IOException {
        public ResourcePropertySource(String location) throws IOException {
    
    
        private ResourcePropertySource(String name, @Nullable String resourceName, Map<String, Object> source) {
    
    
    *************
    普通方法
    
        public ResourcePropertySource withName(String name) {
        public ResourcePropertySource withResourceName() {
    
        private static String getNameForResource(Resource resource) {
    

     

     

    YamlPropertiesFactoryBean

    public class YamlPropertiesFactoryBean extends YamlProcessor implements FactoryBean<Properties>, InitializingBean {
    
    	private boolean singleton = true;
    
    	@Nullable
    	private Properties properties;
    
    	public void setSingleton(boolean singleton) {
    	public boolean isSingleton() {
    
    	public Properties getObject() {
    	public Class<?> getObjectType() {
    
    
    	public void afterPropertiesSet() {
    		if (isSingleton()) {
    			this.properties = createProperties();
    		}
    	}
    
    	protected Properties createProperties() {
    		Properties result = CollectionFactory.createStringAdaptingProperties();
    		process((properties, map) -> result.putAll(properties));
    		return result;
    	}
    
    }
    

     

    YamlProcessor

    public abstract class YamlProcessor {
    
    	private final Log logger = LogFactory.getLog(getClass());
    
    	private ResolutionMethod resolutionMethod = ResolutionMethod.OVERRIDE;
    	private Resource[] resources = new Resource[0];
    
    	private List<DocumentMatcher> documentMatchers = Collections.emptyList();
    	private boolean matchDefault = true;
    	private Set<String> supportedTypes = Collections.emptySet();
    
    
    	public void setDocumentMatchers(DocumentMatcher... matchers) {
    	public void setMatchDefault(boolean matchDefault) {
    	public void setResolutionMethod(ResolutionMethod resolutionMethod) {
    	public void setResources(Resource... resources) {
    	public void setSupportedTypes(Class<?>... supportedTypes) {
    
    
    	protected void process(MatchCallback callback) {
    	protected final Map<String, Object> getFlattenedMap(Map<String, Object> source) {
    	protected Yaml createYaml() {
    
    	private boolean process(MatchCallback callback, Yaml yaml, Resource resource) {
    	private boolean process(Map<String, Object> map, MatchCallback callback) {
    
    	private void handleProcessError(Resource resource, IOException ex) {
    	private Map<String, Object> asMap(Object object) {
    	private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, @Nullable String path) {
    
    
    
    **************
    内部接口
    
    	public interface MatchCallback {
    		void process(Properties properties, Map<String, Object> map);
    	}
    
    
    	public interface DocumentMatcher {
    		MatchStatus matches(Properties properties);
    	}
    
    
    	public enum MatchStatus {
    		FOUND,
    		NOT_FOUND,
    		ABSTAIN;
    
    		public static MatchStatus getMostSpecific(MatchStatus a, MatchStatus b) {
    			return (a.ordinal() < b.ordinal() ? a : b);
    		}
    	}
    
    
    	public enum ResolutionMethod {
    		OVERRIDE,
    		OVERRIDE_AND_IGNORE,
    		FIRST_FOUND
    	}
    
    
    
    **************
    内部类
    
    	private class FilteringConstructor extends Constructor {
    
    		FilteringConstructor(LoaderOptions loaderOptions) {
    			super(loaderOptions);
    		}
    
    		@Override
    		protected Class<?> getClassForName(String name) throws ClassNotFoundException {
    			Assert.state(YamlProcessor.this.supportedTypes.contains(name),
    					() -> "Unsupported type encountered in YAML document: " + name);
    			return super.getClassForName(name);
    		}
    	}
    
    }
    

     

    FactoryBean

    public interface FactoryBean<T> {
    
    	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
    
    	T getObject() throws Exception;
    	Class<?> getObjectType();
    
    	default boolean isSingleton() {
    		return true;
    	}
    
    }
    

     

     

    *******************

    示例

     

    *********************

    配置文件

     

                        

     

    person.yml

    person:
      name: 瓜田李下
      age: 20

     

    *********************

    pojo 层

     

    Person

    @Data
    @Component
    @ConfigurationProperties(prefix = "person")
    @PropertySource(value = {"classpath:properties/person.yml"},factory = YamlPropertySourceFactory.class)
    public class Person {
    
        private String name;
        private Integer age;
    }
    

     

    *********************

    config 层

     

    YamlPropertySourceFactory

    public class YamlPropertySourceFactory implements PropertySourceFactory {
    
        @Override
        public PropertySource<?> createPropertySource(String s, EncodedResource encodedResource) throws IOException {
            Properties properties=loadFromYaml(encodedResource);
            String name=(s!=null?s:encodedResource.getResource().getFilename());
    
            return new PropertiesPropertySource(name,properties);
        }
    
        private Properties loadFromYaml(EncodedResource resource){
            YamlPropertiesFactoryBean yamlPropertiesFactoryBean=new YamlPropertiesFactoryBean();
            yamlPropertiesFactoryBean.setResources(resource.getResource());
            yamlPropertiesFactoryBean.afterPropertiesSet();
    
            return yamlPropertiesFactoryBean.getObject();
        }
    }
    

     

    *********************

    controller 层

     

    HelloController

    @RestController
    public class HelloController {
    
        @Resource
        private Person person;
    
        @RequestMapping("/hello")
        public String hello(){
            System.out.println(person);
    
            return "success";
        }
    }
    

     

     

    *******************

    使用测试

     

    localhost:8080/hello

    2020-07-09 21:48:40.006  INFO 16416 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
    2020-07-09 21:48:40.011  INFO 16416 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
    Person(name=瓜田李下, age=20)
    

    此时,可以使用注解读取yml文件

     

     

    展开全文
  • springboot加载自定义属性文件(@PropertySOurce) ********************** 相关注解 @PropertySource @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Repeatable...

    springboot 加载自定义properties文件(@PropertySOurce)

     

     

    **********************

    相关注解

     

    @PropertySource

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Repeatable(PropertySources.class)
    public @interface PropertySource {
    
        String[] value();    //加载文件位置
    
        String name() default "";
        boolean ignoreResourceNotFound() default false;
        String encoding() default "";
    
        Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
                            //自定义factory,默认不能加载yml文件,可自定义factory
    }
    

     

     

    **********************

    示例

     

    ****************

    属性文件

     

                                  

     

    person.properties

    person.name=瓜田李下
    person.age=20
    

     

    ****************

    pojo 层

     

    Person

    @Data
    @Component
    @ConfigurationProperties(prefix = "person")
    @PropertySource(value = {"classpath:properties/person.properties"})
    public class Person {
    
        private String name;
        private Integer age;
    }
    

     

    ****************

    controller 层

     

    HelloController

    @RestController
    public class HelloController {
    
        @Resource
        private Person person;
    
        @RequestMapping("/hello")
        public String hello(){
            System.out.println(person);
    
            return "success";
        }
    }
    

     

                               

    **********************

    使用测试

     

    localhost:8080/hello

    2020-07-09 20:35:22.908  INFO 6488 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
    2020-07-09 20:35:22.952  INFO 6488 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 43 ms
    Person(name=瓜田李下, age=20)
    

     

     

    展开全文
  • @PropertySource 注解 使用 @PropertySource 注解,可以 PropertySourceFactory 接口 默认使用 @PropertySource 可以指定解析 properties 和 xml 配置文件,却不可以解析 yaml 配置文件,因为 spring 默认没有 yaml ...
  • 使用@PropertySource默认加载的是.xml或者 .properties文件,因为在注解源码默认使用的是DefaultPropertySourceFactory实现处理文件内容,spring 使用ResourcePropertySource从Resource构建Properties传给Spring。 ...
  • 今天遇到一个很诡异的问题 我想把mysql_durid.yml中的配置信息注入到DruidDataSource中 发现根本不起作用 调试源代码发现 mysql_druid.yml中的 spring.database.druid 都...可以重写 PropertySource的 factory 具体.
  • 首先定义一个YamlPropertySourceFactory,参考https://mdeinum.github.io/2018-07-04-PropertySource-with-yaml-files/ import java.io.FileNotFoundException; import java.io.IOException; import java.util....
  • 因为spring中PropertySource的默认实现是properties类型文件的解析。 可以实现一个解析yaml文件的工具类,实现PropertySourceFactory接口。 第一步:实现工具类 public class YamlPropertySourceFactory ...
  • SpringBoot的@PropertySource注解只支持加载 properties结尾的文件。当使用@ConfigurationProperties 注解配合@EnableConfigurationProperties注解将配置转换为JavaBean时,可能需要配合@PropertySource 注解加载...
  • @PropertySource @PropertySource用于项目启动类的的注解,主要功能是加载除application.properties之外的配置文件。 通过配置注解中的value值。达到加载配置文件的目的。value是String[] 类型,可以配置多个文件...
  • 代码: https://github.com/jackhbr/spring-anno/tree/master/myenv这次是看怎么往spring的bean中注入值习惯的同学都知道配置一个扫描,然后@value注解注入即可下面使用自定义的来用这里需要大家了解factorybean,这...
  • 代码: https://github.com/jackhbr/spring-anno/tree/master/myenv这次是看怎么往spring的bean中注入值习惯的同学都知道配置一个扫描,然后@value注解注入即可下面使用自定义的来用这里需要大家了解factorybean,这...
  • 1.自定义配置文件###### #服装 etl.map[10]=服装 etl.map[11]=春秋服 etl.map[12]=半袖衬衣 etl.map[13]=冬罩衣 etl.map[14]=棉衣 etl.map[15]=制式短裤 etl.map[16]=针织背心 #鞋 etl.map[20]=鞋 etl.map[21]=单鞋 ...
  • @PropertySource

    2019-05-29 21:03:00
    功能  加载指定的属性文件(*.properties)到 Spring 的...@PropertySource 和 @Value 组合使用,可以将自定义属性文件中的属性变量值注入到当前类的使用@Value注解的成员变量中。 @PropertySource 和 @Confi...
  • 在项目中,习惯用YAML来写配置文件,但读取自定义配置文件时,遇到了问题: 编写两个配置文件: 1. temp.yml prefix: what: x list: - name: tech item: 123 - name: skill item: 987 2. temp.properties...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 307
精华内容 122
关键字:

自定义propertysource