栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

深入理解spring注解@PropertySource的实现原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深入理解spring注解@PropertySource的实现原理

之前文章简单的介绍了一下@Value和@PropertySource注解的使用,没有看过的同学可以点击查看:

一分钟学会spring注解之@value注解一分钟学会spring注解之@PropertySource注解


今天这篇文章将给大家详细的介绍一下@PropertySource注解实现原理


首先让我们一起看下@PropertySource的源码如下:



@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
   
   String name() default "";
   
   String[] value();
   
   boolean ignoreResourceNotFound() default false;
   
   String encoding() default "";
   
   Class factory() default PropertySourceFactory.class;
}



注意看上面代码中的注释,之前文章有演示过读取classpath中的配置文件,这边演示一下如何读取系统目录中文件如下:



@PropertySource(value={"classpath:/user2.properties","file:/d://user2.properties"},encoding="utf-8",ignoreResourceNotFound=true)



d盘中的user2.properties的配置文件如下:



u.name2=王五
u.age2=25



增加一个user1对象如下:




@Value("${u.name2}")
private String userName;

@Value("${u.age2}")
private Integer age;



运行测试如下:



实例1 === User [userName=李四, age=29]
实例2 === User [userName=王五, age=25]



从上我们可以发现@PropertySource注解的地址可以是以下两种:



  •  classpath路径:"classpath:/com/myco/app.properties"

  •  文件对应路径:"file:/path/to/file"


接下来我们来详细的介绍@PropertySource注解底层是如何解析这些配置文件,这个就必须得PropertySourceFactory的具体实现源码了


进入PropertySourceFactory中你会发现它是一个接口代码如下:



public interface PropertySourceFactory {
   
   PropertySource createPropertySource(String name, EncodedResource resource) throws IOException;
}



里边只有一个createPropertySource方法,进入其中的实现类中如下:



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



注意,重要的类ResourcePropertySource出现了,进去可以看到两个主要的构造方法如下:




   public ResourcePropertySource(String name, EncodedResource resource) throws IOException {
       super(name, PropertiesLoaderUtils.loadProperties(resource));
       this.resourceName = getNameForResource(resource.getResource());
   }
   
   public ResourcePropertySource(EncodedResource resource) throws IOException {
       super(getNameForResource(resource.getResource()), PropertiesLoaderUtils.loadProperties(resource));
       this.resourceName = null;
   }



在构造方法中你可以发现加载资源的地方PropertiesLoaderUtils.loadProperties(resource),一路进去你可以返现如下代码:



static void fillProperties(Properties props, EncodedResource resource, PropertiesPersister persister)
           throws IOException {
       InputStream stream = null;
       Reader reader = null;
       try {
           String filename = resource.getResource().getFilename();
           // 加载xml文件
           if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
               stream = resource.getInputStream();
               persister.loadFromXml(props, stream);
           }
           // 判断是否有需要对应的字符编码设置  有的话处理对应的InputStream
           else if (resource.requiresReader()) {
               reader = resource.getReader();
               persister.load(props, reader);
           }
           else {
               stream = resource.getInputStream();
               persister.load(props, stream);
           }
       }
}



怎么样,是不是可以发现@PropertySource不仅可以解析properties的文件同样也可以解析xml文件,下边我们一起来演示一下解析xml的例子吧

首先新增一个user2.xml如下:






   王二小
   22



配置类增加配置如下:



@PropertySource(value={"classpath:/user.properties","classpath:/user2.xml","file:/d://user2.properties"},encoding="utf-8",ignoreResourceNotFound=false)



测试运行结果如下:



实例1 === User [userName=李四, age=29]
实例2 === User [userName=王二小, age=22]



好了,到目前为止我们不仅学会了@PropertySource注解的使用,而且了解到了其底层的具体实现,做到知其然知其所以然,以及了解了其默认的资源解析器PropertySourceFactory,并且你也可以继承PropertySourceFactory实现自定义的解析器感兴趣的同学可以自己去实现一个自定义解析类


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/239455.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号