Spring Boot数据源属性注入与创建

【Spring Boot】Spring Boot数据源属性注入与创建

一、 前言

在Spring Boot中常常会用到配置文件,最常见的莫过于数据源,基本上都使用配置文件的方式进行配置了,即在application.properties/yml中配置连接数据库的基本信息。

具体在DataSourceBuilder类的build()方法中。

DataSourceBuilder#build():

DataSourceBuilder#maybeGetDriverClassName():

DatabaseDriver#fromJdbcUrl():

DatabaseDriver是个Enum枚举类,列举了所有数据库的驱动。

DatabaseDriver:

二、属性注入与Bean创建

在【Spring Boot】(4)、配置文件值注入文中简单地讲述了配置文件中属性值的注入,本文重新讲述几种属性注入的方法:

@Value注解

Environment环境变量

@ConfigurationProperties和@PropertySource注解

注入全局配置

注入非全局(即外部)配置

在讲述各种属性注入方式的同时,顺便使用该注入方式进行Bean的创建,本文以创建DataSource数据源为例。

2.1、@Value注解

在【Spring Boot】(4)、配置文件值注入文中也讲了使用@Value注解的优缺点。

注意点:如果dbcp2的配置放置在外部配置文件中,必须显式地加载外部配置文件;否则的话,使用@Value就会提示java.lang.IllegalArgumentException: Could not resolve placeholder 'dbcp2.driver' in value "$"的异常信息。

最后创建dbcp2的DataSource的时候,可以直接使用最基本的四个参数值就可以完成Bean的创建。

2.2、Environment环境变量

其实使用Environment变量和使用@Value注解类似,不同的是:@Value是直接将值注入到具体的属性上,而Environment是把所有的配置项添加到环境变量中,然后在取值的时候使用getProperty(key)方法即可。

注意点:使用Environment环境变量和使用@Value注解一样,对于外部配置文件需要显式加载。

EnvironmentgetProperty()有个重载的方法:

如果使用getProperty(key),如果key不存在的时候,方法返回null,而不会报异常,这跟@Value有些区别。如果使用getProperty(key, defaultValue),见名思意,即当key不存在的时候,可以使用指定的默认值代替。

2.3、@ConfigurationProperties和@PropertySource注解2.3.1、注入全局配置属性

@EnableConfigurationProperties启动配置功能,将对应的DruidProperties配置类与全局配置文件(默认)中的以druid为前缀的配置项进行绑定并注入,并将DruidProperties配置类注入到Spring的IOC环境中。这个时候就可以创建一个DruidDataSource的Bean。

此时创建的DataSource中包含了基本的四个属性值,就能执行数据库操作了。

2.3.2、注入外部配置属性

还是同全局配置中的属性值一样,只是将其提取到druid.properties中了。

在DruidProperties中加入@PropertySource("classpath:druid.properties")一行,提示Spring Boot从外部druid.properties中读取属性值。

DruidConfig.java同上小节的一样,保持不变。

在运行的时候,却会发现DruidProperties并未注入,即数据源的四个属性值都未正常注入。在调试的时候,发现DruidProperties的属性setter方法并未进入。

其实注入外部配置属性的时候,需要手动将该类注册为组件,即使用@Component或者@Configuration注解才行。与此同时,由于DruidConfig类上有个@EnableConfigurationProperties(DruidProperties.class)注解,既然已经手动在DruidProperties上添加了@Component或者@Configuration注解使其成为组件,那么就无需再在DruidConfig上通过再将DruidProperties注册为组件,否则会在自动注入使用DruidProperties的时候会找到两个Bean,导致出现org.springframework.beans.factory.NoUniqueBeanDefinitionException唯一性异常。

代码如下:

三、疑问?

在第2.3.1小节中讲述到,使用@EnableConfigurationProperties会将其属性value对应的配置类与配置文件绑定,并将其注入到Spring IOC容器中。而对于第2.3.2小节中,既然有这个功能,为什么还要在配置类上加上组件注解吗?

其实博主在调试的时候,发现Spring IOC容器中确实有配置类的Bean,但是就是没办法进入到属性注入的setter方法中。在博主历经N次调试后才发现,在使用@PropertySource(s)注解引入外部配置文件的时候,如果不在配置类上手动添加组件注解的话,该配置文件就无法加载到Spring环境中,导致想要给配置类属性进行注入的时候就不能成功执行,只能是null了。

下图是不使用注解时,环境中的数据:

如果使用注解的话,环境中就多了外部配置文件信息:

总结:要想使用外部配置文件进行注入的话,必须要使用组件注解才能成功。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180516G0F96J00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券