当前位置: 首页 > news >正文

{Spring Boot 原理篇} Spring Boot自动装配原理

@SpringBootApplication

1,Spring Boot 应用启动,@SpringBootApplication标注的类就是启动类,它去实现配置类中的Bean的自动装配

@SpringBootApplication
public class SpringbootRedis01Application {public static void main(String[] args) {SpringApplication.run(SpringbootRedis01Application.class, args);}}

2,而@SpringBootApplicatiozn注解中包含了三个注解:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//以上四个都为元注解,以下三个才是去实现自动装配的注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}
), @Filter(type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class}
)}
)

@SpringBootConfiguration

这个注解包含了@Configuration,@Configuration里面又包含了一个@Component注解,也就是

说,这个注解标注在哪个类上,就表示当前这个类是一个配置类,而配置类也是spring容器中的组

件,

@SpringBootConfiguration:对@Configuration 注解的封装,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中。

@EnableAutoConfiguration

这个注解是开启自动配置的功能核心注解,里面包含了两个注解

@AutoConfigurationPackage

@Import({AutoConfigurationImportSelector.class})

@AutoConfigurationPackage:

将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器,这也就是为什么我们在利用springboot进行开发的时候,无论是Controller还是Service的路径都是与主配置类同级或者次级的原因。

@Import(AutoConfigurationImportSelector.class)

上一个注解我们把所有组件都加载到了容器里面,这个注解就是将需要自动装配的类以全类名的方

式返回

1、AutoConfigurationImportSelector这个类里面有一个方法selectImports(),如下

2、在selectImport()方法里调用了一个getAutoConfigurationEntry()方法,这个方法里面又调用

了一个getCandidateConfigurations()方法

3、在getCandidateConfigurations()方法里面调用了loadFactoryNames()方法、

 4、loadFactoryNames()方法里面又调用了一个loadSpringFactories()方法

5、关键就在这个loadSpringFactories()方法里面,在这个方法里,它会查找所有在META-INF

6、在META-INF/spring.factories这个文件里面的数据是以键=值的方式存储,然后解析这些文

件,找出以EnableAutoConfiguration为键的所有值,以列表的方式返回

@ComponentScan

这个注解的作用就是扫描当前包及子包的注解

@Condition注解就是在自动装配的时候如果这个类中有此注解而且满足其定义的逻辑,是否要注入容器。

定义自己的条件类,实现Condition口重写match方法

public class ClassCondition implements Condition {
//条件为是否导入相应坐标而且是单个条件
//    @Override
//    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//        boolean flag=true;
//        try {
//            Class<?> clas= Class.forName("redis.clients.jedis.Jedis");
//        } catch (ClassNotFoundException e) {
//
//           flag=false;
//        }
//
//        return flag;
//    }
//条件为是否导入相应坐标而且是多个条件@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {boolean flag=true;Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClasss.class.getName());String[] value = (String[]) map.get("value");try {for(String className :value) {Class<?> clas = Class.forName(className);}} catch (ClassNotFoundException e) {flag=false;}return flag;}
}

定义配置类:@Condition(value属性指的就是条件类)

@Configuration
public class UserConfig {@Bean
//    @Conditional(value = ClassCondition.class)@ConditionOnClasss(value={"com.alibaba.fastjson.JSON","redis.clients.jedis.Jedis"})public Hotel hotel(){return new Hotel();}@Bean
//    @Conditional(value = ClassCondition.class)
//    @ConditionOnClasss(value={"com.alibaba.fastjson.JSON","redis.clients.jedis.Jedis"})@ConditionalOnProperty(value = "k1",havingValue = "k2")public Hotel hotel2(){return new Hotel();}}

Condition – 小结

自定义条件:

① 定义条件类:自定义类实现Condition接口,重写 matches 方法,在 matches 方法中进行逻辑判 断,返回 boolean值 。

        matches 方法两个参数:

                • context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。

                • metadata:元数据对象,用于获取注解属性。

② 判断条件: 在初始化Bean时,使用 @Conditional(条件类.class)注解

SpringBoot 提供的常用条件注解: 

          以下注解在springBoot-autoconfigure的condition包下 :

ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化

Bean ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean

ConditionalOnBean:判断环境中有对应Bean才初始化Bean 可以查看RedisAutoConfiguration类说明以上注解使用 距离演示ConditionalOnProperty

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Tracy 小笔记:微信小程序 mpx 雷达图的实现
  • godot新建项目及设置外部编辑器为vscode
  • Python --NumPy库基础方法(1)
  • MySQL C API的介绍
  • HarmonyOS鸿蒙应用开发-ZRouter让系统路由表变得更简单
  • ubuntu实践
  • 从数据时代到智能时代,星环科技信雅达联合发布金融全栈解决方案
  • latex 表格处理
  • 初阶数据结构——二叉树大汇总
  • 【Android Compose】ListView效果
  • 《操作系统》(学习笔记)(王道)
  • Pytorch使用教学6-张量的分割与合并
  • UE4Editor.exe运行与调试 “-run=XX” 命令行
  • LabVIEW放大器自动测量系统
  • PHP设计模式-简单工厂模式
  • 【刷算法】从上往下打印二叉树
  • Android单元测试 - 几个重要问题
  • CEF与代理
  • idea + plantuml 画流程图
  • Linux快速复制或删除大量小文件
  • SSH 免密登录
  • Vultr 教程目录
  • 创建一个Struts2项目maven 方式
  • 前端自动化解决方案
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • ​2020 年大前端技术趋势解读
  • ​批处理文件中的errorlevel用法
  • #162 (Div. 2)
  • #FPGA(基础知识)
  • %@ page import=%的用法
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (算法)前K大的和
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .cfg\.dat\.mak(持续补充)
  • .NET : 在VS2008中计算代码度量值
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .net core 的缓存方案
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NetCore 如何动态路由
  • .Net中wcf服务生成及调用
  • .Net转前端开发-启航篇,如何定制博客园主题
  • :“Failed to access IIS metabase”解决方法
  • @Query中countQuery的介绍
  • @SpringBootConfiguration重复加载报错
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [Android Studio] 开发Java 程序
  • [autojs]逍遥模拟器和vscode对接
  • [C#学习笔记]注释
  • [C++] Windows中字符串函数的种类
  • [C++]运行时,如何确保一个对象是只读的
  • [CISCN 2019华东南]Web11