【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注解一样,对于外部配置文件需要显式加载。
Environment的getProperty()有个重载的方法:
如果使用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了。
下图是不使用注解时,环境中的数据:
如果使用注解的话,环境中就多了外部配置文件信息:
总结:要想使用外部配置文件进行注入的话,必须要使用组件注解才能成功。
领取专属 10元无门槛券
私享最新 技术干货