@PropertySource注解是Spring用于加载配置文件,默认支持.properties.xml两种配置文件。@PropertySource属性如下:

  • name:默认为空,不指定Spring自动生成
  • value:配置文件
  • ignoreResourceNotFound:没有找到配置文件是否忽略,默认false,4.0版本加入
  • encoding:配置文件编码格式,默认UTF-8 4.3版本才加入
  • factory:配置文件解析工厂,默认:PropertySourceFactory.class 4.3版本才加入,如果是之前的版本就需要手动注入配置文件解析Bean

接下来就使用@PropertySource来加载.properties.xml配置文件。这里模拟连接MySQL数据库。

首先添加依赖:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.6.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>

准备属性配置文件jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306
jdbc.userName=root
jdbc.password=xiaohu

创建属性实体类来加载配置文件JdbcProperties

@Data
@Repository
@PropertySource(value = "classpath:jdbc.properties")
public class JdbcProperties {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.userName}")
private String userName;
@Value("${jdbc.password}")
private String password;
}

创建JDBC配置类JdbcConfig

@Component
public class JdbcConfig {
@Bean
public DataSource dataSource(JdbcProperties jdbcProperties){
System.out.println("打印获取到的配置信息:"+jdbcProperties);
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(jdbcProperties.getDriver());
dataSource.setUrl(jdbcProperties.getUrl());
dataSource.setUsername(jdbcProperties.getUserName());
dataSource.setPassword(jdbcProperties.getPassword());
return dataSource;
}
}

创建Spring配置类SpringConfiguration

@Configuration
public class SpringConfiguration { }

创建测试类测试读取配置文件

public class PropertySourceTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("config");
DataSource dataSource = context.getBean("dataSource",DataSource.class);
System.out.println(dataSource);
}
}

查看输出结果:

打印获取到的配置信息:JdbcProperties(driver=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://127.0.0.1:3306, userName=root, password=xiaohu)
org.springframework.jdbc.datasource.DriverManagerDataSource@58695725

从结果可以看出,我们的properties中的配置已经成功读取到,并且DataSource也从Spring容器中获取到。上面介绍注解的属性时,factory是4.3版本才加入的,那么如果4.3版本之前要解析配置文件又应该怎么处理呢?,这个时候就需要手动将解析配置文件的Bean注入到Spring容器中了,用法很简单,在SpringConfiguration类中添加如下代码即可:

@Bean
public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
return new PropertySourcesPlaceholderConfigurer();
}

具体测试结果,就自行测试了。上面例子介绍了properties的使用,下面我们将配置文件换成xml文件。配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="jdbc.driver">com.mysql.cj.jdbc.Driver</entry>
<entry key="jdbc.url">jdbc:mysql://127.0.0.1:3306/test</entry>
<entry key="jdbc.userName">root</entry>
<entry key="jdbc.password">xiaohu</entry>
</properties>

然后将JdbcProperties类上的注解的配置文件换成xml文件。

@PropertySource(value = "classpath:jdbc.properties")

其他不用调整,执行测试类,输出的结果一样。因为上面介绍到@PropertySource默认支持propertiesxml的配置文件。我们可以查看PropertySourceFactory的默认实现DefaultPropertySourceFactory源码

public class DefaultPropertySourceFactory implements PropertySourceFactory {

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

然后进入ResourcePropertySource类,源码这里使用了一个三元运算符,如果name为空,就使用默认Spring默认生成的name

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方法,进入到源码

public static Properties loadProperties(EncodedResource resource) throws IOException {
Properties props = new Properties();
fillProperties(props, resource);
return props;
}

会调用fillProperties的方法,一直跟到调用最低的fillProperties方法。

static void fillProperties(Properties props, EncodedResource resource, PropertiesPersister persister)
throws IOException {
InputStream stream = null;
Reader reader = null;
try {
String filename = resource.getResource().getFilename();
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
stream = resource.getInputStream();
persister.loadFromXml(props, stream);
}
else if (resource.requiresReader()) {
reader = resource.getReader();
persister.load(props, reader);
}
else {
stream = resource.getInputStream();
persister.load(props, stream);
}
}
finally {
if (stream != null) {
stream.close();
}
if (reader != null) {
reader.close();
}
}
}

第一个if判断文件后缀是否是xml结尾,常量XML_FILE_EXTENSION如下:

private static final String XML_FILE_EXTENSION = ".xml";

除了支持propertiesxml的配置文件方式,也支持yml配置文件的方式,不过需要自定义解析工厂,下面来实现怎么解析yml配置文件。引入可以解析yml文件的第三方库

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

创建yml解析工厂YamlPropertySourceFactory实现PropertySourceFactory

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

然后将JdbcProperties类的@PropertySource换成如下写法:

@PropertySource(value = "classpath:jdbc.yml",factory = YamlPropertySourceFactory.class)

执行测试类,输出结果与上面结果一样

打印获取到的配置信息:JdbcProperties(driver=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://127.0.0.1:3306, userName=root, password=xiaohu)
org.springframework.jdbc.datasource.DriverManagerDataSource@58695725

证明我们自定义的解析yml配置文件就成功了。

Spring的@PropertySource注解使用的更多相关文章

  1. spring中@PropertySource注解的使用

    概述: The @PropertySource annotation provides a convenient and declarative mechanism for adding aPrope ...

  2. 【译】Spring 4 @PropertySource和@Value注解示例

    前言 译文链接:http://websystique.com/spring/spring-propertysource-value-annotations-example/ 本篇文章将展示如何通过@P ...

  3. Springboot中PropertySource注解的使用

    https://blog.csdn.net/qq_30739519/article/list/3 注解 https://blog.csdn.net/qq_30739519/article/detail ...

  4. Spring的基础注解

    Spring的基础注解 1.注解的概述 注解是为了便于程序的调试而用于代替配置文件的一种程序语法,与配置文件具有互换性.通常基于注解编程的程序更加简洁. (注:使用Spring注解必须导入aop包) ...

  5. spring 、spring boot 常用注解

    @Profile 1.用户配置文件注解. 2.使用范围: @Configration 和 @Component 注解的类及其方法, 其中包括继承了 @Component 的注解: @Service. ...

  6. 朱晔和你聊Spring系列S1E9:聊聊Spring的那些注解

    本文我们来梳理一下Spring的那些注解,如下图所示,大概从几方面列出了Spring的一些注解: 如果此图看不清楚也没事,请运行下面的代码输出所有的结果. Spring目前的趋势是使用注解结合Java ...

  7. Spring 部分常用注解

    最近在Spring-MVC的项目,把一些自己在项目中使用到的注解整理一下. 1.@Controller 对应表现层的Bean,也就是Struts中对应的Action: 使用这个注解之后,就是把当前Be ...

  8. Spring基于纯注解方式的使用

    经过上篇xml与注解混合方式,对注解有了简单额了解,上篇的配置方式极大地简化了xml中配置,但仍有部分配置在xml中进行,接下来我们就通过注解的方式将xml中的配置用注解的方式实现,并最终去掉xml配 ...

  9. Spring 常用的注解

    目录 Spring 常用的注解 前言 SpringMVC配置 web配置 @ComponentScan @PropertySource @PropertySources @Value @Control ...

随机推荐

  1. Java:Java单例中的懒汉和饿汉模式

    1.懒汉模式 懒汉模式:在类加载的时候不被初始化,懒汉式是延时加载,他是在需要的时候才创建对象. public class JdbcUtil { //定义私有的引用 private static Jd ...

  2. java设计模式(9):模板方法模式(TemplateMethod)

    一,定义:模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 二,类图: 三,通过小例子讲解: 这个模式一般用在 ...

  3. 数据库表的自增ID createDate和updateDate 用JPA注解代替触发器实现

    对于数据库表的自增ID , createDate和updateDate 等字段,用JPA注解代替触发器实现,效率会高很多. 由于这些属性很多entity都有 可以写成两个基本entity :BaseE ...

  4. yum的卸载和安装

    安装精髓:报错就查,少包就按. 一.如果yum没有注册则需要卸载再安装第三方yum 1.卸载redhat的默认安装yum包 [root@dsl ~]#rpm –qa | grep yum [root@ ...

  5. 如何修改Windows 11 任务栏大小

    1.首先Win+R输入regedit打开注册表编辑器         2.进入注册表编辑器后,在地址栏中输入: HKEY_CURRENT_USER\Software\Microsoft\ Window ...

  6. 灵魂画手的零基础python教程1:关于Python学习的误区、python的优缺点、前景

    滴~ 近段时间,因为工作项目的原因,阿菌要重拾起python这门语言了,所以顺势写一门python教程,精心的编排,配上漫画和视频,希望能帮助更多想接触编程的同学入门,课程将从基础语法开始讲起,和大家 ...

  7. luogu2594 [ZJOI2009]染色游戏

    做法其他题解已经说得很清楚了,但似乎没有对于本题 SG 函数正确性的证明,我来口胡一下( 证明: 猜想: \[\operatorname{SG}(i,j)=\begin{cases}\operator ...

  8. python使用笔记007-内置函数,匿名函数

    1.匿名函数 匿名函数也是一个函数,是一个简单的函数,没有名字,只能实现一些简单的功能 1 #匿名函数也是一个函数,是一个简单的函数,没有名字,只能实现一些简单的功能 2 lambda x:x+1#入 ...

  9. 团队开发day06

    实现功能,通过连接,获取到品牌商存入数据库的数据, 将数据返回到list集合,展示在安卓前端 出现问题:servlet响应请求返回数据格式出错,利用gson类将java类 转化为jsonobject对 ...

  10. Vue.js源码解析-Vue初始化流程之动态创建DOM

    目录 前言 一._update 如何判断是初始化还是更新操作? 二.patch 2.1 patch 定义 2.2 初始化的 patch 三.createElm 动态创建DOM 3.1 创建组件节点 3 ...