SpringBoot 自动配置
📖Condition注解
Condition 是在Spring 4.0 增加的条件判断功能,通过这个功能,可以动态地、选择性的创建 Bean 操作。
步骤
-
编写pom文件(添加该坐标,选择性在容器中自动配置注入了RedisTemplate模板类)
2.启动器
可理解为 用坐标当作选择的判断依据(是否注入模板类)
案例一
在 Spring 的 IOC 容器中有一个 User 的 Bean,
现要求:导入Jedis坐标后,加载该Bean,没导入,则不加载。
步骤
-
建实体类User
-
用@Condition注解进行条件判断
-
启动类
第一种方法
-
编写配置类实现类
@Conditional(value=“Condition的实现类字节码文件”)
编写Condition实现类进行条件逻辑代码
此种方法在代码里写死了,未来更改坐标需要重复更改实现类代码
第二种方法(动态演变)
-
编写一个注解
2. 编写配置类实现类
3. 编写配置类
案例二:系统自带的注解
若条件不满足则会报空指针异常错误(因为条件不满足则无法注入bean)
📖@Enable注解
底层原理是使用@Import注解导入一些配置类,实现Bean的动态加载
而@Import提供4中用法:
① 导入Bean(注入普通类)
② 导入配置类(并将配置类中的内容加载运行)
③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类
④ 导入 ImportBeanDefinitionRegistrar 实现类。
@SpringBootApplication中有@ComponentScan注解, 扫描范围:当前引导类所在包及其子包
当前引导类所在包com.xinxin.springbootenable03
注入user类所在包com.xinxin.springbootenable_other04.config
因此扫描不到,所以容器中没有user
解决方案:
1.使用@ComponentScan扫描com.apesource.springbootenable_other04.config包
2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
3.可以对Import注解进行封装。
第一种
第二种
Import4中用法:
1. 导入Bean
2. 导入配置类
3. 导入ImportSelector的实现类
查看ImportSelector接口源码
String[] selectImports(AnnotationMetadata importingClassMetadata);
代表将“字符串数组”中的的类,全部导入spring容器
4. 导入ImportBeanDefinitionRegistrar实现类
第三种
第四种
📖@EnableAutoConfiguration注解
1. 主启动类
2. @SpringBootApplication注解内部
1. @ComponentScan 对应XML配置中的元素。
作用:自动扫描并加载符合条件的组件或者bean ,将这个bean定义加载到IOC容器中
2. @SpringBootConfiguration
作用:SpringBoot的配置类 ,标注在某个类上
3. @AutoConfigurationPackage 自动配置包
4. @EnableAutoConfiguratio 开启自动配置功能
5. @Import({AutoConfigurationImportSelector.class}) :给容器导入组件
总结:
-
@EnableAutoConfiguration 注解内部使用@Import(AutoConfigurationImportSelector.class) 来加载配置类。
-
配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean
-
并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean
📖自定义启动器⭐️⭐️⭐️
自定义redis-starter,要求当导入redis坐标时,SpringBoot自动创建Jedis的Bean
步骤(共4步):
1️⃣在项目子目录下创建redis-spring-boot-autoconfigure模块
autoConfigure模块需要删除启动类和测试类,它不需要单独测试,打包运行。
-
autoConfigure模块进行自动配置,在该项目的pom文件中添加Jedis坐标
-
将Jedis注入到Spring容器中,编写一个配置类,在配置类中向容器直接注入Jedis对象。
💨如果SpringBoot项目能够加载到autoConfigure模块里的这个配置类,那么这个Jedis就成功注入容器中了!!!
但是启动类只加载启动类所在的包路径下文件及子目录,无法加载其他包路径下的文件。
解决方案:
-
在autoConfigure模块里的reource目录下,编写一个META-INF文件夹,在其内编写spring-factories文件
Springboot 容器扫描所有依赖包的 META-INF/spring.factories 文件,然后可以通过这个文件的内容反射具体的类,加载到 springboot 中。
2️⃣在项目子目录下创建redis-spring-boot-starter模块 即SpringBoot启动器项目(注意命名规范)
启动器项目扮演的是模块的角色,后期是需要被导入的,是不能打包运行的,所以不能有启动类、测试类、主配置文件
-
在启动类项目的pom文件里导入redis-spring-boot-autoconfigure模块
3️⃣建一个自动配置SpringBoot的项目
-
在自动配置的SpringBoot项目中的pom.xml导入redis-spring-boot-starter模块的坐标(项目名、版本号、组织名称)后项目中就注入Jedis
4️⃣运行
👏升级一下
将jedis连接ip端口写成动态的
-
在SpringBoot项目中的yml文件内配置端口和ip
-
在redis-spring-boot-autoconfigure模块创建RedisProperties类,加载yml文件键值对数据,批量注入。
-
改写redis-spring-boot-autoconfigure模块中的配置类
-
运行
✔如若想要让其访问之前的端口,只需在autoconfigure模块中配置类方法上添加该注解即可
@ConditionalOnMissingBean(Jedis.class)