1.自定义Bean属性绑定
- 在配置文件application.yml 中配置参数
servers:
ipAddress: 192.168.0.1
port: 2345
timeout: -1
(注:不要写成server 这个是默认属性给tomcat服务器配置参数的)
- 创建实体类(Bean)
其中实体类的属性对应配置文件中配置的参数,相当于读取 配置文件 中的内容
@Data
//lombok自动生成get set方法
@Component
//使spring容器能够扫描到此类并注入到bean中
@ConfigurationProperties(prefix = "servers")
//加载配置文件中的属性 前缀为services 内容会自动按照属性名对应
public class ServerConfig {
private String ipAddress;
private int port;
private long timeout;
}
注:@Data
使用lombok插件 自动生成get / set 方法,记得现在pom.xml中导入Lombok的坐标。
@Component
Spring中的注解,使spring容器能够扫描到此类 自动封装为Bean 交与容器管理
@ConfigurationProperties(prefix = "servers")
加载配置文件中的属性 前缀为services 内容会自动按照属性名对应进行读取
- 获取自定义的Bean
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
//获取容器对象
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
//通过类名获取Bean
ServerConfig bean = run.getBean(ServerConfig.class);
System.out.println(bean);
}
}
springboot启动类中 ConfigurableApplicationContext
是获取spring容器对象 ,然后通过容器对象获取其中的ServerConfig类
对应的Bean ,就是我们自定义的Bean
输出结果:
2.第三方bean属性绑定
以 数据源druid 为例
- 在pom.xml中导入第三方库坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
- 在配置类中创建Bean
可以在任意的配置类中 加载 数据源druid 的Bean,配置类就是可以被spring容器描扫到的类,一种简单的实现方式自己创建一个类加上@Component
注解就可以当作一个配置类,比如之前的ServerConfig类。
SpringBoot的启动类 @SpringBootApplication
注解 中包含很多注解其中就有@Component
因此可以在启动类中配置Bean
@SpringBootApplication
public class Demo05Application {
//通过 @Bean 创建Bean
@Bean
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
public static void main(String[] args) {
//获取容器对象
ConfigurableApplicationContext run = SpringApplication.run(Demo05Application.class, args);
DruidDataSource dataSource = run.getBean(DruidDataSource.class);
System.out.println(dataSource);
}
}
- 输出结果:
输出一堆参数,且参数值均没有初始化,这是由于Druid是懒加载,只有连接数据库时才会初始化
如何给第三方Bean注入数据
通过创建Bean的时候直接给某属性赋值 或者配置文件 读入
- 直接赋值
@Bean
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver456");
return dataSource;
}
- 配置文件读入
datasource:
driverClassName: com.mysql.jdbc.Driver456
加@ConfigurationProperties(prefix = "datasource")
注解读入配置文件数据
@Bean
@ConfigurationProperties(prefix = "datasource")
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
return dataSource;
}
输出结果:
前面我们一直说配置类,配置类是什么?
配置类就是可以被spring容器加载的类,一种简单的实现方式是 自己创建一个类加上@Component
注解就可以当作一个配置类。
- 缺点: 如果我们有几十个类,哪些类是配置类哪些类不是呢?我们总不能一个个去看有没有
@Component
注解,这样看起来很混乱
我们使用另一个注解 @EnableConfigurationProperties({类名...})
参数为一个数组,数组中的元素就是 配置类的类名。 比如:@EnableConfigurationProperties(ServerConfig.class)
(只有一个元素{}可省略)
此时同样可以获取 Bean 及 Bean所绑定的属性值
注:如果使用@EnableConfigurationProperties()
注解,那么@Component
就要去除,否则会报 NoUniqueBeanDefinitionException
每个Bean都是独一无二的,两个注解造成Bean冲突了
3.松散绑定
3.1属性绑定模式
@ConfigurationProperties
注解绑定属性支持属性名松散绑定
以ServerConfig类为例
@ConfigurationProperties(prefix = "servers")
public class ServerConfig {
private String ipAddress;
private int port;
private long timeout;
}
支持的属性绑定模式:
- 驼峰模式
servers:
ipAddress: 192.168.0.1
port: 2345
timeout: -1
- 下划线模式
servers:
ip_address: 192.168.0.1
port: 2345
timeout: -1
- 中划线模式
servers:
ip-address: 192.168.0.1
port: 2345
timeout: -1
- 常量模式
servers:
IP_ADDRESS: 192.168.0.1
port: 2345
timeout: -1
- 任意模式
servers:
IP_ADD_R-E_SS: 192.168.0.1
port: 2345
timeout: -1
总结:@ConfigurationProperties
注解支持属性松散绑定,属性名大小写忽略、下划线 _ 、中划线 - 忽略。
注: 支持松散绑定的是@ConfigurationProperties
注解,其他注解比如@Value就不支持,而springboot官方建议使用前者
3.2绑定前缀名命名规范
@ConfigurationProperties
注解中的参数也就是prefix前缀名的命名规范:
仅能使用纯小写字母、数字、下划线作为合法的字符
比如这样写就不合法
@ConfigurationProperties(prefix = "Servers")
控制台报错信息
Configuration property name 'Servers' is not valid:
Invalid characters: 'S'
Bean: Servers-com.xue.config.ServerConfig
Reason: Canonical names should be kebab-case ('-' separated), lowercase alpha-numeric characters and must start with a letter
注:并非是我们配置文件属性名是servers,而这边前缀名是Servers 大小写不匹配的问题,即使配置文件属性名改为Servers,依旧会报相同的错误,这是由于绑定前缀名命名规范的问题。
事实上,在修改 绑定前缀名命名 为 Servers 时,编译器就会报错
4.Bean的属性校验
Bean的属性一般都有自己的格式或者类型,比如 端口 port 是数字并且要在规定范围内 ,如果我们写成字符就不行了,不是说不能用port属性,而是port属性作为tomcat服务器端口号注入的时候会报错。所以我们需要属性校验
- 在pom.xml中导入JSR303规范接口坐标,并导入 hibernate框架提供的校验器做实现类
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!-- 使用hibernate框架提供的校验器做实现类-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
注:这些依赖都没有写版本号,这是由于spring-boot-starter-parent 总的坐标默认有版本控制,这些依赖都有对应整合好的版本号
- 对需要进行属性校验的Bean添加
@Validated
注解 开启属性校验
@Data
@ConfigurationProperties(prefix = "servers")
//加载配置文件中的属性 前缀为services 内容会自动按照属性名对应
@Validated
//开启对当前bean的属性注入校验
public class ServerConfig {
private String ipAddress;
private int port;
private long timeout;
}
- 设置具体的规则
@Data
@ConfigurationProperties(prefix = "servers")
//加载配置文件中的属性 前缀为services 内容会自动按照属性名对应
@Validated
//开启对当前bean的属性注入校验
public class ServerConfig {
@Max(value = 8888,message = "最大值不能超过8888")
@Min(value = 202,message = "最小值不能低于202")
private String ipAddress;
private int port;
private long timeout;
}
输出结果: