Spring Boot自动设置原理

打印 上一主题 下一主题

主题 1603|帖子 1603|积分 4809

当想实验利用第三方工具包依赖时在项目中假如第三方工具包文件不在Spring Boot项目包及其子包下则这个工具包所声明的Bean对象和设置类并不会被Spring Boot扫描到,就不能利用。解决方案如下
方案一:在Spring Boot启动类添加@ComponentScan注解组件扫描,手动声明要扫描的包的位置(利用繁琐,性能低)
方案二:通过@Import注解导入,被@Import导入的类会被Spring Boot加载到IOC容器中成为Bean对象
利用情势主要有三种:1.导入普通类,2.导入设置类,3.导入ImportSelector接口实现类(在ImportSelect接口中有一个selectImports方法,他的作用是将要管理的类通过全类名的情势给IOC容器进行管理,成为IOC容器中的Bean),4 .通过EnableXXX注解封装@Import注解
缺陷:在导入第三方依赖时要知道导入哪些设置类和Bean对象,比力繁琐用户体验不好,在导入第三方依赖时只有第三方最清晰必要导入哪些设置类和Bean对象。这时候一般由第三方依赖自己提供一个注解,一般以Enable开头,用EnableXXX注解封装@Import注解。这时只必要在启动类上添加这个注解即可
第四个方法也是SpringBoot采用的方法
源码跟踪解析SpringBoot自动设置原理:

在启动类中有一个@SpringBootApplication注解这是Spring Boot最紧张的注解,进去会发现封装了很多注解,主要关心@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan 三个注解

在Spring Boot中具备包扫描作用,默认扫描当前包及其子类,原因就是@SpringBootApplication注解封装了@ComponentScan注解,@ComponentScan是组件扫描的注解
@SpringBootConfiguration中封装了@Configuration注解,这个注解作用是用来声明当前类也是一个设置类,以是才气做到在启动类中声明Bean对象


@EnableAutoConfiguration前面提到Enable开头的注解一般都封装了@Import注解,通过@Import注解导入指定的Bean对象或设置类。点进@EnableAutoConfiguration注解发现@impact注解导入的是AutoConfigurationImportSelector.class,这是一个ImportSelector接口的实现类

点进去发现AutoConfigurationImportSelector实现了DeferredImportSelector接口,而这个DeferredImportSelector继续了ImportSelector接口。

前面提到ImportSelector中有个selectImports方法,这个方法会以全类名的情势将必要的类导入到IOC容器中进行管理。
也就是说,我们必要在AutoConfigurationImportSelector中找到这个selectImports方法看哪些类被加载到IOC容器,这样就能知道在启动Spring Boot项目时哪些类会被自动导入到IOC容器中

首先 selectImports 方法中要返回这个 autoConfigurationEntry.getConfigurations()这个参数,这就是要给IOC管理的Bean对象或设置类,那么我们必要关心这个参数里是什么东西。
由图可知他是通过这个 this.getAutoConfigurationEntry() 方法给 autoConfigurationEntry.getConfigurations() 赋值,以是点进去这个方法看

在 this.getAutoConfigurationEntry() 这个方法中他创建了一个 configurations 聚集通过 this.getCandidateConfigurations(annotationMetadata, attributes); 方法来给autoConfigurationEntry.getConfigurations() 参数赋值,以是必要关心这个方法在做什么,点进方法去看看

方法如图所示,他调用了SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); 这个方法给 configurations 赋值 并调用了断言判空 Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
版本不同提示的信息不同,以下图片是Spring Boot 2.7.5提示的信息



大概我们不知道这个赋值的方法在做什么但是通过断言提示的报错内容可以猜到他的功能,假如 configurations 为空则提示没有找到这个自动设置类在这个文件里,也就是说这个方法会去加载这份文件里所设置的信息。找到文件打开后会发现里面都是写好的全类名,这样这些全类名就会被加载到IOC容器中
这样就能表明在Spring Boot项目中当我们引入某些依赖时通过@Autowired注入就可以直接利用这个类对象,是由于Spring Boot在启动时就帮我们加载好这个依赖的设置类或Bean对象给IOC容器管理。
但是不是所有的Bean都会被加载到IOC容器中Spring Boot会根据@Conditional注解条件去加载Bean,在声明Bean对象时能看到@ConditionalOnClass、@ConditionalOnMissingBean,@ConditionalOnProerty,这些都是@Conditional衍生出的常用的子注解,
@ConditionalOnClass判断环境中是否有对应字节码文件,有才注册Bean到IOC容器
@ConditionalOnMissingBean判断环境中没有对应的Bean(根据类型或名称),才注册Bean到IOC容器 (这个通常用于声明默认的Bean,意思是假如用户已经声明了这个Bean,则利用用户自己的,假如没有则Spring Boot自动声明这个Bean)
@ConditionalOnProerty判断设置文件中有对应属性和值,才注册Bean到容器。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

缠丝猫

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表