SpringBoot
【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】
SpringBoot 原理篇
文章目录
- SpringBoot
- SpringBoot 原理篇
- 1 自动配置
- 1.12 bean 的加载控制【注解式】
- 1.12.1 问题引入
- 1.12.2 bean的加载控制【注解式】
- 1.12.3 小结
1 自动配置
1.12 bean 的加载控制【注解式】
1.12.1 问题引入
前面我们通过硬编码的形式完成了根据需求来控制某个bean 的加载,
但是这样就很容易想到问题,这样子代码量就太大了,而且每出现一种情况,就要整一个if 判断
而且还会出现,判断语句压根儿写不出来的情况
【有简单点儿的办法吗?当然】
1.12.2 bean的加载控制【注解式】
使用@Conditional注解的派生注解设置各种组合条件控制bean的加载
直接开干
先把原先的做法注掉
现在在配置中通过@Bean 注解主动加载一个bean
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.Cat;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
public class SpringConfig {
@Bean
public Cat tom(){
return new Cat();
}
}
直接运行
现在来控制它
先换下坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.4</version>
</dependency>
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.Cat;
import com.dingjiaxiong.bean.Mouse;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
public class SpringConfig {
@Bean
@ConditionalOnClass(Mouse.class) //现在的意思就是只要发现了有老鼠,就创建猫
public Cat tom(){
return new Cat();
}
}
直接运行
没毛病
如果我现在想换成狼,就不能用这种形式了,因为我们压根儿没有这个类
换个注解
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.Cat;
import com.dingjiaxiong.bean.Mouse;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
public class SpringConfig {
@Bean
// @ConditionalOnClass(Wolf.class)
@ConditionalOnMissingClass("com.dingjiaxiong.bean.Wolf")
public Cat tom(){
return new Cat();
}
}
现在的意思就是如果我没有加载到Wolf,那我就加载猫
直接运行
OK,因为压根儿没有Wolf,所以Cat 可以被加载
如果改成Mouse
其实之前那个注解也可以,毕竟都能直接导入类了,那还有啥判断的必要?
改成Wolf
OK,没毛病
这是通过类,还可以根据容器中是否有bean 来进行判断
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.Cat;
import com.dingjiaxiong.bean.Mouse;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
@Import(Mouse.class)
public class SpringConfig {
@Bean
// @ConditionalOnClass(name = "com.dingjiaxiong.bean.Wolf")
@ConditionalOnBean(name = "com.dingjiaxiong.bean.Mouse")
public Cat tom(){
return new Cat();
}
}
直接运行
有老鼠,有猫
如果tom 只想“等” Jerry
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.Cat;
import com.dingjiaxiong.bean.Mouse;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
@Import(Mouse.class)
public class SpringConfig {
@Bean
@ConditionalOnBean(name = "jerry")
public Cat tom(){
return new Cat();
}
}
运行
如果给Mouse 加上名
现在的老鼠是Jerry 了,tom 就出来了
再来个场景,就算Jerry 在了,但是如果狗在,tom 还是不出来
package com.dingjiaxiong.config;
import com.dingjiaxiong.bean.Cat;
import com.dingjiaxiong.bean.Mouse;
import com.dingjiaxiong.bean.MyImportSelector;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Import;
/**
* ClassName: SpringConfig
* date: 2022/10/25 10:34
*
* @author DingJiaxiong
*/
@Import(Mouse.class)
public class SpringConfig {
@Bean
@ConditionalOnBean(name = "jerry")
@ConditionalOnMissingClass("com.dingjiaxiong.bean.Dog")
public Cat tom(){
return new Cat();
}
}
运行结果
OK,有狗,tom 不会出来
当然其实还有特别多可以进行判定的注解
试试判断非web 项目
当然现在的配置都是写在配置类中使用@bean 注解
以后不一定要用这种格式
package com.dingjiaxiong.bean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
import org.springframework.stereotype.Component;
/**
* ClassName: Cat
* date: 2022/10/25 10:32
*
* @author DingJiaxiong
*/
@Component("tom")
@ConditionalOnNotWebApplication
@ConditionalOnBean(name = "jerry")
public class Cat {
}
直接在类上也可以
配置类上扫一下
运行看看
有Jerry、非web,条件都满足,tom 就出现了
OK,回顾一下
匹配指定类
未匹配指定类
匹配指定类型的bean
匹配指定名称的bean
匹配指定名称的bean
匹配指定环境
所以这个东西有什么用?
举个栗子,假如我现在要用数据库,
先导入一个坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.11</version>
</dependency>
【以往的写法】
@Bean
public DruidDataSource dataSource(){
return new DruidDataSource();
}
运行
没啥问题,已经上来了
假如我现在不用数据库, 这个东西就没必要加载了
现在就可以整一个判定
@Bean
@ConditionalOnClass(name = "com.mysql.jdbc.Driver")
public DruidDataSource dataSource(){
return new DruidDataSource();
}
运行结果
这样就不会加载了
如果我们现在又加上MySQL 的驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
再次运行
就是这样
匹配指定环境
1.12.3 小结
- 使用@ConditionalOn***注解为bean的加载设置条件