详解Spring中的@PropertySource注解使用

作者:懵懂小虎 时间:2023-05-05 06:40:15 

@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配置文件就成功了。

来源:https://www.cnblogs.com/tenghu/p/15159414.html

标签:Spring,@PropertySource,注解
0
投稿

猜你喜欢

  • C# 文件下载之断点续传实现代码

    2021-05-24 15:37:02
  • Mybatis单个参数的if判断报异常There is no getter for property named 'xxx' in 'class java.lang.Integer'的解决方案

    2023-10-16 14:56:01
  • Mybatis-Plus设置全局或者局部ID自增的实现

    2021-11-27 00:30:03
  • Android编程实现获取当前连接wifi名字的方法

    2023-11-24 15:41:50
  • C#去除字符串中的反斜杠实例(推荐)

    2022-02-02 20:27:14
  • Entity Framework配置关系

    2023-10-15 09:45:30
  • Android开发实现TextView超链接5种方式源码实例

    2022-12-10 16:50:32
  • Idea自动生成Entity实现过程详解

    2022-06-03 12:18:24
  • Android中使用ZXing生成二维码(支持添加Logo图案)

    2023-12-24 21:34:58
  • 详解JAVA中的Collection接口和其主要实现的类

    2021-06-20 19:14:08
  • java面试try-with-resources问题解答

    2023-09-03 15:08:01
  • Java中遍历ConcurrentHashMap的四种方式详解

    2023-11-17 08:54:41
  • C#如何给PDF文件添加水印

    2021-07-20 14:32:36
  • springmvc无法访问/WEB-INF/views下的jsp的解决方法

    2023-11-23 15:15:38
  • 详解Zookeeper基础知识

    2023-07-31 08:03:45
  • DevExpress实现GridView当无数据行时提示消息

    2023-08-23 04:13:33
  • Java开发必备的三大修饰符

    2021-10-19 10:11:01
  • Java实现SMS短信通发送手机验证码案例讲解

    2022-05-14 22:37:57
  • C# 获取系统进程的用户名

    2022-12-06 02:38:03
  • C#设计模式之职责链模式示例详解

    2023-11-08 05:26:38
  • asp之家 软件编程 m.aspxhome.com