定义/作用

@PropertySource注解用于指定资源文件读取的位置,它不仅能读取properties文件,也能读取xml文件,并且通过YAML解析器,配合自定义PropertySourceFactory实现解析YAML文件。

源码:

//只能作用在类上
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {/*** 指定资源名称,如果为空,就根据基础资源的描述生成。*/String name() default "";/*** 指定资源路径。* 可以是 classpath:/xxx/xxxx* 也可以是 file:/xxx/xxx/xx*/String[] value();/*** 是否忽略资源不存在的情况,如果不忽略,当资源不存在时就报错。默认不忽略。* 此属性时spring4.0以后出现的。*/boolean ignoreResourceNotFound() default false;/*** 指定资源文件的编码格式。如果不指定就使用文件默认的。* 此注解是spring4.3以后出现的。*/String encoding() default "";/*** 指定资源工厂,如果不指定,就使用默认的资源工厂。*/Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;}

使用方式:

此注解在spring4.3之前与spring4.3及之后使用的方式不一样。

错误demo:

//配置类
@Configuration
@ComponentScan(basePackages = "propertysourcedemo")
public class SpringConfig {//通过SPEL表达式注入属性@Value("${druid.driverClassName}")private String driverClassName;@Value("${druid.url}")private String url;@Value("${druid.username}")private String username;@Value("${druid.password}")private String password;//注册Druid数据源连接池@Beanpublic DruidDataSource druidDataSource(){System.out.println("driverClassName====> " + driverClassName);System.out.println("url====> " + url);System.out.println("username====> " + username);System.out.println("username====> " + username);DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driverClassName);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);return druidDataSource;}
}//测试类
public class PropertySourceDemoTest {private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);@Testpublic void PropertySourceDemoTest() throws SQLException {//从容器中获取数据源DruidDataSource druidDataSource = (DruidDataSource) context.getBean("druidDataSource");//获取数据库连接Connection connection = druidDataSource.getConnection();System.out.println(druidDataSource);System.out.println(connection);connection.close();}
}

文件:

结果:

原因:
因为没有指定资源配置文件,所以spring不知道去哪找配置 文件进行属性注入,找不到,然后SPEL表达式就把属性的key直接解析成字面量。

spring4.3之前

spring4.3之前,除了使用@PropertySource注解之外,还要手动注册一个资源文件解析器PropertySourcesPlaceholderConfigurer到IOC容器中。并且如果使用Bean注解注册资源文件解析器,方法要是static方法。

@Configuration
@ComponentScan(basePackages = "propertysourcedemo")
@PropertySource(value = "classpath:daoconfig/datasource-config.properties")
public class SpringConfig {//通过SPEL表达式注入属性@Value("${druid.driverClassName}")private String driverClassName;@Value("${druid.url}")private String url;@Value("${druid.username}")private String username;@Value("${druid.password}")private String password;//创建资源文件解析器,spring4.3之前必须要的,不要就无法解析。@Beanpublic static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){return new PropertySourcesPlaceholderConfigurer();}//注册Druid数据源连接池@Beanpublic DruidDataSource druidDataSource(){System.out.println("driverClassName====> " + driverClassName);System.out.println("url====> " + url);System.out.println("username====> " + username);System.out.println("username====> " + username);DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driverClassName);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);return druidDataSource;}
}//测试类不变

结果:

如果把资源解析器去掉:

没有效果。

spring4.3及之后

4.3之后,就可以直接使用,因为spring会使用默认的DefaultPropertySourceFactory解析。

@Configuration
@ComponentScan(basePackages = "propertysourcedemo")
//这次使用file协议的url路径来解析
@PropertySource(value = "file:///D:/spring-high-level-study/src/main/resources/daoconfig/datasource-config.properties")
public class SpringConfig {//通过SPEL表达式注入属性@Value("${druid.driverClassName}")private String driverClassName;@Value("${druid.url}")private String url;@Value("${druid.username}")private String username;@Value("${druid.password}")private String password;//注册Druid数据源连接池@Beanpublic DruidDataSource druidDataSource(){System.out.println("driverClassName====> " + driverClassName);System.out.println("url====> " + url);System.out.println("username====> " + username);System.out.println("username====> " + username);DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driverClassName);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);return druidDataSource;}
}

结果:

读取XML文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties><entry key="druid.driverClassName">com.mysql.jdbc.Driver</entry><entry key="druid.url">jdbc:mysql://127.0.0.1/db1?useUnicode=true&amp;characterEncoding=UTF-8</entry><entry key="druid.username">root</entry><entry key="druid.password">5201314..a</entry></properties>

把配置类的@PropertySource注解路径修改成xml文件,也可以解析。

boolean ignoreResourceNotFound() default false;

当资源不存在时,是否忽略,默认不忽略,也就是会报错。

设置为false时:

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [propertysourcedemo.config.SpringConfig]; nested exception is java.io.FileNotFoundException: D:\spring-high-level-study\src\main\resources\daoconfig\datasource-config1.xml (系统找不到指定的文件。)

设置为true忽略时:

与不配置该注解时一个样。因为找不到指定资源文件后,spring也不知道去哪找资源文件了。

自定义PropertySourceFactory解析YAML文件:

PropertySourceFactory的默认实现DefaultPropertySourceFactory是解析不了yaml文件的,如果要解析,就要自定义实现。

我们就不自己解析Yaml,直接引用第三方jar包进行解析。

 <dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.23</version></dependency>

代码:

/*** @author YeHaocong* @decription 自定义Yaml解析工厂*/public class YAMLPropertySourceFactory implements PropertySourceFactory {@Overridepublic org.springframework.core.env.PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) throws IOException {//创建一个YAML解析工厂。YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();//设置资源。factory.setResources(encodedResource.getResource());//获取解析后的Properties对象Properties properties = factory.getObject();//返回。此时不能像默认工厂那样返回ResourcePropertySource对象 ,要返回他的父类PropertiesPropertySource对象。return name != null ? new PropertiesPropertySource(name, properties) :new PropertiesPropertySource(encodedResource.getResource().getFilename(),properties);}
}//配置类:@Configuration
@ComponentScan(basePackages = "propertysourcedemo")
//使用自定义工厂。
@PropertySource(value = "classpath:daoconfig/datasource-config.yaml",factory = YAMLPropertySourceFactory.class)
public class SpringConfig {//通过SPEL表达式注入属性@Value("${druid.driverClassName}")private String driverClassName;@Value("${druid.url}")private String url;@Value("${druid.username}")private String username;@Value("${druid.password}")private String password;//注册Druid数据源连接池@Beanpublic DruidDataSource druidDataSource(){System.out.println("driverClassName====> " + driverClassName);System.out.println("url====> " + url);System.out.println("username====> " + username);System.out.println("password====> " + password);DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(driverClassName);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);return druidDataSource;}
}

结果:

Spring高级之注解@PropertySource详解(超详细)相关推荐

  1. Spring高级之注解@Bean详解(超详细)

    定义/作用 当我们要使用第三方类实现组件注册到IOC容器时,例如第三方数据库连接池等,我们无法修改他们的代码,所以我们不能通过@Component及其衍生注解来进行组件定义.这是,可以通过@Bean注 ...

  2. Spring高级之注解@ComponentScan详解(超详细)

    定义/作用 @ComponentScan注解用于实现spring主键的注解扫描,会扫描特定包内的类上的注解. 源码(对属性进行一些简介,会在后文中详细讲解每个属性): @Retention(Reten ...

  3. Spring高级之注解@DependsOn详解(超详细)

    定义/作用 @DependsOn注解可以定义在类和方法上,意思是我这个组件要依赖于另一个组件,也就是说被依赖的组件会比该组件先注册到IOC容器中. 使用场景: 需要用到观察者模式的情况下通常都需要用到 ...

  4. Spring高级之注解@lazy详解(超详细)

    定义/作用 用于指定单例bean实例化的时机,在没有指定此注解时,单例会在容器初始化时就被创建.而当使用此注解后,单例对象的创建时机会在该bean在被第一次使用时创建,并且只创建一次.第二次及以后获取 ...

  5. Spring 3.0 注解注入详解

    Spring 3.0 注解注入详解 2011-04-15 09:44 17ZOUGUO ITEYE博客 我要评论(1) 字号:T | T AD: 一.各种注解方式 1.@Autowired注解(不推荐 ...

  6. Java 泛型详解(超详细的java泛型方法解析)

    Java 泛型详解(超详细的java泛型方法解析) 1. 什么是泛型 泛型:是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型.也就是说在泛型使用过程中,操作的数据类型被指定为 ...

  7. spring : springmvc常用注解标签详解(转)

    新的项目,新的学习,好久没用这些注解了,同时在学习使用shiro ,lucene 等等.在网上找了些博文,感谢作者的总结和分享. 欢迎交流,言归正传: 1.@Controller 在SpringMVC ...

  8. @Autowired注解详解——超详细易懂

    @Autowired详解 要搞明白@Autowired注解就是要了解它是什么?有什么作用?怎么用?为什么? 首先了解一下IOC操作Bean管理,bean管理是指(1)spring创建对象 (2)spr ...

  9. 斜率优化详解(超详细, 有图有代码有注释)

    文章目录 斜率优化引入 从例题开始 斜率优化Part 1: 推为斜率式 斜率优化Part 2: 合法点集的斜率单调性 Part 3: 找到最优决策点 Part 4: 斜率优化大流程 Part 5: 斜 ...

最新文章

  1. SAP Retail Execution Overview
  2. efcore调用函数_EFCore执行Sql语句的方法:FromSql与ExecuteSqlCommand
  3. 可穿戴的脑机接口设备将运动意念转化为行动
  4. python【数据结构与算法】一维前缀和与差分
  5. Linux集群和自动化维3.1 Python语言的应用领域
  6. 联想拯救者Y7000系列笔记本电脑外接显示器解决方案
  7. Usage of git
  8. php中的file_upload,PHP文件上传(PHP file upload)
  9. fastdfs java qps,关于vsftpd与fastDFS的问题?
  10. Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(8)...
  11. 无类型指针、空指针和野指针
  12. Postfix邮件服务系统
  13. Enterprise Library 4.0 - May 2008 发布了
  14. easytrader 量化交易平台连接同花顺软件使用平安证券
  15. 如何科学预估开发时间
  16. 计算机硬盘只显示c盘,电脑只显示C盘我们应该怎么办
  17. 携职教育:四川2022年人力资源管理师考试报名通知
  18. BootStrap笔记-下拉菜单的使用
  19. docker部署OpenVAS开源漏洞扫描系统——筑梦之路
  20. 蓝奏云PHP解析接口,蓝奏云下载地址解析API[直链]

热门文章

  1. 【POJ1584】A Round Peg in a Ground Hole,第一次的计算几何
  2. 11.频域里的卷积——介绍,傅里叶变换和卷积,快速傅里叶变换(FFT)_1
  3. 二叉树C++ | 广度优先遍历(层级顺序遍历)_2
  4. bzoj1038 [ZJOI2008]瞭望塔 枚举
  5. 2017.4.24 聪明的质检员 思考记录
  6. linux防火墙服务关闭,Linux防火墙(firewall)的开启与关闭
  7. 【英语学习】【Level 07】U08 Old Stories L5 Fulfilling a life goal
  8. OpenGL坐标系及基本变换
  9. Java程序员晋升之路:“Java高级核心知识全面解析
  10. SQL server 数据库 (函数篇 2)