Spring Boot自动装配原理

简介: Spring Boot自动装配原理以及源码深入
  • 前言
  • SpringBoot是一个脚手架,通常喜欢拿SpringBoot和Spring做比较,SpringBoot只是对于SSM框架开发时候的配置项做了一个默认配置,将开发中约定大于配置进行了实现,大大节约了开发时间写各种繁琐的配置文件环节,达到了开箱即用的便捷体验
  • SpringBoot入口
// 源码入口就是 @SpringBootApplication注解@SpringBootApplicationpublicclassBootDemoApplication {
publicstaticvoidmain(String[] args) {
SpringApplication.run(BootDemoApplication.class, args);
    }
}


  • 查看@SpringBootApplication注解
@Inherited@SpringBootConfiguration@EnableAutoConfiguration// 自动装配原理的核心注解@ComponentScan(excludeFilters= { @Filter(type=FilterType.CUSTOM, classes=TypeExcludeFilter.class),
@Filter(type=FilterType.CUSTOM, classes=AutoConfigurationExcludeFilter.class) })
public@interfaceSpringBootApplication {
  • 查看@EnableAutoConfiguration注解
@Inherited@AutoConfigurationPackage/*** 自动装配的时候使用的是@Import注解* 作用是导入一个或者多个组件搭配@Configuration注解使用,交给spring容器管理* 该注解有三种方式* 1.@import:指定导入一个或者多个类* 2.ImportSelector:定义一个类实现该接口,重写selectImports方法* 3.* 扩展:@ImportResource:指定导入一个或者多个xml文件*/@Import(AutoConfigurationImportSelector.class)
public@interfaceEnableAutoConfiguration {
  • AutoConfigurationImportSelector类源码解析
// 重写来自于DeferredImportSelector.Group#process@Overridepublicvoidprocess(AnnotationMetadataannotationMetadata, DeferredImportSelectordeferredImportSelector) {
Assert.state(deferredImportSelectorinstanceofAutoConfigurationImportSelector,
                 () ->String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
// 获取自动装配信息AutoConfigurationEntryautoConfigurationEntry= ((AutoConfigurationImportSelector) deferredImportSelector)
        .getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (StringimportClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
    }
}
// 获取自动装配信息protectedAutoConfigurationEntrygetAutoConfigurationEntry(AnnotationMetadataannotationMetadata) {
if (!isEnabled(annotationMetadata)) {
returnEMPTY_ENTRY;
    }
AnnotationAttributesattributes=getAttributes(annotationMetadata);
// 加载所有在META-INF/spring.factories中配置的类 跳到①List<String>configurations=getCandidateConfigurations(annotationMetadata, attributes);
configurations=removeDuplicates(configurations);
Set<String>exclusions=getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// 经过condition注解过滤后的自动配置类configurations=getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
returnnewAutoConfigurationEntry(configurations, exclusions);
}
// ① META-INF/spring.factories中读取所有的候选的自动配置类名称protectedList<String>getCandidateConfigurations(AnnotationMetadatametadata, AnnotationAttributesattributes) {
// 通过SpringFactoriesLoader读取所有的候选的自动配置类名称// ② 加载配置候选的类List<String>configurations=SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
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.");
returnconfigurations;
}
// ③ 加载配置候选的类protectedClass<?>getSpringFactoriesLoaderFactoryClass() {
returnEnableAutoConfiguration.class;
}
// 所以如果想要将一个外部(第三方)的类交给spring容器管理,可以把这个类配置添加到META-INF/spring.factories文件中。// 例如自定义starter场景启动器
  • 总结:SpringBoot的自动装配原理本质上就是读取项目中所有的META-INF/spring.factories的配置类信息


  • @Import之 ImportSelector/ImportBeanDefinitionRegistrar扩展
// ImportSelector (重要!SpringBoot底层使用这种方式,但是又有区别)publicclassMyImportSelectorimplementsImportSelector {
@OverridepublicString[] selectImports(AnnotationMetadataimportingClassMetadata) {
// 返回值String[]中值依旧是要导入类的全限定名,注意,返回值可以是空数组但是不能为nullreturnnewString[]{"com.fun.bootdemo.custome.Demo1"};
    }
}
/*** SpringBoot底层使用的是:* org.springframework.boot.autoconfigure.AutoConfigurationImportSelector* 该类实现的是DeferredImportSelector接口,该接口包含有额外功能:* gruop 该分组可以用来进行排序和过滤时同时DeferredImportSelector是优先级比较低的,* 需要等到其他bean注册完了。才注册该接口导入的bean。这个功能很好的结合了@Conditon等条件注解* 实现了用户自定义配置覆盖默认配置*/// ImportBeanDefinitionRegistrarpublicclassMyImportBeanDefinitionRegistrarimplementsImportBeanDefinitionRegistrar {
@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata, BeanDefinitionRegistryregistry) {
// 指定注册bean定义信息RootBeanDefinitionrootBeanDefinition=newRootBeanDefinition(Demo3.class);
// demo3 是beanNameregistry.registerBeanDefinition("demo3", rootBeanDefinition);
    }
}
// 测试 (在配置类上)@Import({MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})


相关文章
|
24天前
|
XML Java 开发者
Spring Boot开箱即用可插拔实现过程演练与原理剖析
【11月更文挑战第20天】Spring Boot是一个基于Spring框架的项目,其设计目的是简化Spring应用的初始搭建以及开发过程。Spring Boot通过提供约定优于配置的理念,减少了大量的XML配置和手动设置,使得开发者能够更专注于业务逻辑的实现。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,为开发者提供一个全面的理解。
28 0
|
17天前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
28天前
|
Java Spring
SpringBoot自动装配的原理
在Spring Boot项目中,启动引导类通常使用`@SpringBootApplication`注解。该注解集成了`@SpringBootConfiguration`、`@ComponentScan`和`@EnableAutoConfiguration`三个注解,分别用于标记配置类、开启组件扫描和启用自动配置。
54 17
|
17天前
|
消息中间件 Java 数据库
解密Spring Boot:深入理解条件装配与条件注解
Spring Boot中的条件装配与条件注解提供了强大的工具,使得应用程序可以根据不同的条件动态装配Bean,从而实现灵活的配置和管理。通过合理使用这些条件注解,开发者可以根据实际需求动态调整应用的行为,提升代码的可维护性和可扩展性。希望本文能够帮助你深入理解Spring Boot中的条件装配与条件注解,在实际开发中更好地应用这些功能。
24 2
|
17天前
|
Java 容器
springboot自动配置原理
启动类@SpringbootApplication注解下,有三个关键注解 (1)@springbootConfiguration:表示启动类是一个自动配置类 (2)@CompontScan:扫描启动类所在包外的组件到容器中 (3)@EnableConfigutarion:最关键的一个注解,他拥有两个子注解,其中@AutoConfigurationpackageu会将启动类所在包下的所有组件到容器中,@Import会导入一个自动配置文件选择器,他会去加载META_INF目录下的spring.factories文件,这个文件中存放很大自动配置类的全类名,这些类会根据元注解的装配条件生效,生效
|
26天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
39 2
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
66 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
2月前
|
Java Spring 容器
springboot @RequiredArgsConstructor @Lazy解决循环依赖的原理
【10月更文挑战第15天】在Spring Boot应用中,循环依赖是一个常见问题,当两个或多个Bean相互依赖时,会导致Spring容器陷入死循环。本文通过比较@RequiredArgsConstructor和@Lazy注解,探讨它们解决循环依赖的原理和优缺点。@RequiredArgsConstructor通过构造函数注入依赖,使代码更简洁;@Lazy则通过延迟Bean的初始化,打破创建顺序依赖。两者各有优势,需根据具体场景选择合适的方法。
84 4
|
2月前
|
Java Spring 容器
Spring底层原理大致脉络
Spring底层原理大致脉络
|
2月前
|
XML 前端开发 Java
拼多多1面:聊聊Spring MVC的工作原理!
本文详细剖析了Spring MVC的工作原理,涵盖其架构、工作流程及核心组件。Spring MVC采用MVC设计模式,通过DispatcherServlet、HandlerMapping、Controller和ViewResolver等组件高效处理Web请求。文章还探讨了DispatcherServlet的初始化和请求处理流程,以及HandlerMapping和Controller的角色。通过理解这些核心概念,开发者能更好地构建可维护、可扩展的Web应用。适合面试准备和技术深挖
46 0