栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot自动装配原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot自动装配原理

SpringBoot自动装配原理 一、什么是自动装配

SpringBoot定义了一套接口规范,在这套规范中SpringBoot启动的时候会扫描外部导入的各种start中的meta-INF/spring.factories文件,将文件中的配置信息加载到Spring容器中。即可以理解为:通过注解或者一些简单的配置就能在Spring Boot的帮助下实现某块功能

二、如何实现SpringBoot的自动装配
  1. 首先从SpringBoot的核心注解@SpringBootApplication入手
  2. 点击@SpringBootApplication可知该注解有以下注解组成:
//前四个是java的元注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited

//后三个是spring的注解
@SpringBootConfiguration  //类似于@Configuration表示该类是配置类
@EnableAutoConfiguration  //启用SpringBoot 的自动配置机制(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })  //扫描组件
  1. 重点分析@EnableAutoConfiguration注解:
    3.1@EnableAutoConfiguration组成:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@Inherited
@AutoConfigurationPackage //将main包下所有组件注册到容器中
@import(AutoConfigurationimportSelector.class)
public @interface EnableAutoConfiguration {...}

3.2 重点分析AutoConfigurationimportSelector:自动加载配置类

public class AutoConfigurationimportSelector implements DeferredimportSelector, BeanClassLoaderAware,
		ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered 

该类实现了DeferredimportSelector接口,因此实现了selectimports()方法,该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IoC 容器中。

public String[] selectimports(Annotationmetadata annotationmetadata) {
		//判断自动装配开关是否打开
		if (!isEnabled(annotationmetadata)) {
			return NO_importS;
		}
		//获取所有需要装配的bean
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationmetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

因此分析getAutoConfigurationEntry(annotationmetadata)方法

protected AutoConfigurationEntry getAutoConfigurationEntry(Annotationmetadata annotationmetadata) {
	//1.判断是否可以自动装配(默认是true)
	if (!isEnabled(annotationmetadata)) {
		return EMPTY_ENTRY;
	}
	//2.获取EnableAutoConfiguration注解中的 exclude 和 excludeName
	AnnotationAttributes attributes = getAttributes(annotationmetadata);
	//3.从各个meta-INF/spring.factories文件中获取到所有配置类
	List configurations = getCandidateConfigurations(annotationmetadata, attributes);
	configurations = removeDuplicates(configurations);
	Set exclusions = getExclusions(annotationmetadata, attributes);
	checkExcludedClasses(configurations, exclusions);
	configurations.removeAll(exclusions);
	4.
	configurations = getConfigurationClassFilter().filter(configurations);
	fireAutoConfigurationimportEvents(configurations, exclusions);
	return new AutoConfigurationEntry(configurations, exclusions);

对以上2、3、4步dubug图示:
第二步:用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName

第三步:从各个meta-INF/spring.factories文件中获取到所有配置类

第四步:根据注解@ConditionalOnXXX进行过滤,满足条件的类才会生效

4. SpringBoot中常见的条件注解:

@ConditionalOnBean:当容器里有指定 Bean 的条件下
@ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
@ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选Bean
@ConditionalOnClass:当类路径下有指定类的条件下
@ConditionalOnMissingClass:当类路径下没有指定类的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnexpression:基于 SpEL 表达式作为判断条件
@ConditionalOnJava:基于 Java 版本作为判断条件
@ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
@ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
@ConditionalOnWebApplication:当前项目是 Web 项 目的条件下
三、实现自定义start
  1. 创建一个mycustomer-spring-boot-start模块,定义好Person类,PersonService、MyConfig这三个类


  2. 在resources目录下创建一个meta-INF目录,并创建一个spring.factories文件,仿照spring-boot-autoconfigure中的spring.factories文件去定义。
  3. 通过maven中的install命令将模块进行打包,发布到本地仓库中。
  4. 测试,创建一个模块进行测试,引入刚才打成jar包的坐标。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/299341.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号