Spring Boot自动装配过程解析及简单Demo演示
文章目录
- 1、约定大于配置
- 2、自动装配原理
- 2.1、`@SpringBootApplication`
- 2.2、`@EnableAutoConfiguration`
- 2.3、`@Import`
- 2.4、`AutoConfigurationImportSelector.class`
- 2.5、`selectImports()方法`
- 3、简单Demo
- 3.1、装配目标
- 3.2、配置属性类
- 3.3、自动装配类
- 3.4、spring.factories文件
- 3.5、使用组件
Spring Boot 是由 Pivotal 团队提供的全新框架,其采用 约定大于配置的方式来大量的减少了普通Spring MVC应用的初始搭建、配置过程。
1、约定大于配置
约定大于配置是一种软件设计范式,简单来说就是简化配置,即用户只需要在Maven-pom文件中添加相关依赖包,在application.yml中配置必要部分(如数据库链接、redis链接、rabbitmq链接等)就行了,可以直接启动项目而不用写一行xml配置。
通过Maven快速创建Spring Boot项目的过程简介如下:https://blog.csdn.net/weixin_44360895/article/details/112060112
2、自动装配原理
Spring Boot通过main方法启动SpringApplication类的静态方法run()来启动项目。
@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}
}
2.1、@SpringBootApplication
@SpringBootApplication注解标注是一个Spring Boot应用,它是一个复合注解:
@SpringBootConfiguration注解其实就携带了一个@Configuration注解,可以认为@SpringBootConfiguration = @Configuration;
2.2、@EnableAutoConfiguration
@AutoConfigurationPackage是自动配置包注解,作用和@ComponentScan一样,也是将主配置类所在的包及其子包里面的组件扫描到IOC容器中,但是两个注解扫描的对象是不同的。@AutoConfigurationPackage扫描的是@Enitity、@MapperScan等第三方依赖注解标注的类,@ComponentScan只扫描@Controller、@Service、@Component、@Repository等注解标注的类。
2.3、@Import
@Import是自动装配的核心注解,导入AutoConfigurationImportSelector类。
关于@Import注解的作用详见:https://blog.csdn.net/weixin_44360895/article/details/112758122
2.4、AutoConfigurationImportSelector.class
AutoConfigurationImportSelector这个类需要关注的核心就是它其实是实现了ImportSelector接口:
这个过程是运用了@Import注解的第二种用法,重写了selectImports()方法,返回自动配置类的全类名的string[ ]数组后,这些自动配置类就会被叫给Spring容器管理。
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}
}
2.5、selectImports()方法
selectImports()方法是如何返回自动配置类的全类名的string[ ]数组的呢?
我们先进入其中的getAutoConfigurationEntry()方法,再进入其中的getCandidateConfigurations()方法,可以看到它是通过SpringFactoriesLoader.loadFactoryNames()方法进行加载的。
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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.");return configurations;
}
我们进入到SpringFactoriesLoader类的loadFactoryNames()方法,发现它是去加载META-INF/spring.factories文件。
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {String factoryClassName = factoryClass.getName();return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);if (result != null) {return result;} else {try {Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");LinkedMultiValueMap result = new LinkedMultiValueMap();while(urls.hasMoreElements()) {URL url = (URL)urls.nextElement();UrlResource resource = new UrlResource(url);Properties properties = PropertiesLoaderUtils.loadProperties(resource);Iterator var6 = properties.entrySet().iterator();while(var6.hasNext()) {Entry<?, ?> entry = (Entry)var6.next();String factoryClassName = ((String)entry.getKey()).trim();String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());int var10 = var9.length;for(int var11 = 0; var11 < var10; ++var11) {String factoryName = var9[var11];result.add(factoryClassName, factoryName.trim());}}}cache.put(classLoader, result);return result;} catch (IOException var13) {throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);}}
}
另外注意到SpringFactoriesLoader.loadFactoryNames()方法的第一个参数,传的是EnableAutoConfiguration.class
protected Class<?> getSpringFactoriesLoaderFactoryClass() {return EnableAutoConfiguration.class;
}
EnableAutoConfiguration类的全类名刚好是META-INF/spring.factories中的key值,
SpringFactoriesLoader会根据这个键去所有spring.factories中找所对应的values,并返回。如mybatis的spring.factories:
至此Spring Boot自动装配过程结束。
3、简单Demo
下面我们写一个简单的组件,并让Spring Boot自动装配它。
要先明确自动装配的对象:
假如你要自动装配一个女朋友来代替你的右手^_^
……
首先可以用创建Spring Boot项目的方式创建一个简单的Maven项目,然后删掉App启动类、application.yml文件、test单元测试包、修改pom.xml文件,整体代码结构如下:
pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.1.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.xmotor</groupId><artifactId>girl-spring-boot-starter</artifactId><version>0.0.1-SNAPSHOT</version><name>girl-spring-boot-starter</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!--这是Spring Boot的核心启动器,包含了自动配置、日志和YAML。--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!--此注解的作用是给自定义的配置类生成元数据信息,让我们在application.yml中写配置的时候有提示……--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><!--打包时忽略启动类--><configuration><skip>true</skip></configuration></plugin></plugins></build></project>
其中关于spring-boot-configuration-processor依赖的作用具体见:https://blog.csdn.net/weixin_43328357/article/details/106993172
3.1、装配目标
定义一个自动装配的目标类,即你想得到的对象,比如一个女朋友……
//自动配置的目的就是创建这个类
public class Girl {private String name;//姓名private Integer age;//年龄private String face;//颜值public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getFace() {return face;}public void setFace(String face) {this.face = face;}public String doSomething(){return "我的女朋友是-- 姓名:"+this.name+",年龄:"+this.age+",颜值:"+this.face;}
}
3.2、配置属性类
这个类的作用是获取application.yml中配置的属性值
@ConfigurationProperties(prefix = "com.xmotor.girl")
public class GirlProperties {private String name;//姓名private Integer age;//年龄private String face;//颜值private Boolean isCreateGirl;//是否创建女朋友public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getFace() {return face;}public void setFace(String face) {this.face = face;}public Boolean getCreateGirl() {return isCreateGirl;}public void setCreateGirl(Boolean createGirl) {isCreateGirl = createGirl;}
}
3.3、自动装配类
这个类是给@Import注解去加载的,在此类中创建目标类。
@Configuration
@ConditionalOnClass(Girl.class)//当引入Girl类时创建
@EnableConfigurationProperties(GirlProperties.class)//让GirlProperties属性类生效
public class GirlAutoConfigure {@Autowiredprivate GirlProperties girlProperties;@Bean@ConditionalOnMissingBean//当没有此实例时才创建@ConditionalOnProperty(prefix = "com.xmotor.girl",value = "isCreateGirl",havingValue = "true")//有这个值时才创建public Girl getGirl(){Girl girl = new Girl();girl.setName(girlProperties.getName());girl.setAge(girlProperties.getAge());girl.setFace(girlProperties.getFace());return girl;}
}
3.4、spring.factories文件
在resources资源文件夹下创建META-INF文件夹及spring.factories文件,内容如下:
#-------starter自动装配---------
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xmotor.girlspringbootstarter.GirlAutoConfigure
自此女朋友组件创建完成,通过maven-install安装到本地或maven-deploy发布到依赖仓即可使用。
3.5、使用组件
在pom.xml中引入依赖:
<dependency><groupId>com.xmotor</groupId><artifactId>girl-spring-boot-starter</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
在application.yml中配置你的女朋友的属性:
com:xmotor:girl:name: 林志玲age: 18face: 漂亮isCreateGirl: true
随便写个方法看看你创建的女朋友还满意不:
@RestController
@RequestMapping("/test")
public class TestController {@Autowiredprivate Girl girl;@RequestMapping("/test1")public Object test1(){String aaa = girl.doSomething();System.out.println(aaa);return aaa;}
}
print:
我的女朋友是-- 姓名:林志玲,年龄:18,颜值:漂亮
以上就是Spring Boot的自动装配过程解析及简单Demo演示,不足之处欢迎斧正。
Spring Boot自动装配过程解析及简单Demo演示相关推荐
- Spring Boot自动装配原理详解
目录 1.环境和依赖 1.1.spring boot版本 1.2.依赖管理 2.自动装配 2.1.流程概述 2.2.三大步前的准备工作 2.2.1.注解入口 2.2.2.获取所有配置类 2.3.获取过 ...
- Spring Boot 自动装配的原理
在Spring Boot中,不得不说的一个点是自动装配,它是Starter的基础,也是Spring Boot的核心,那么什么叫自动装配呢?或者说什么叫装配呢? 简单来说,就是自动将Bean装配到IoC ...
- Spring Boot - 自动装配中的不可忽视的@Import
文章目录 Pre 四种处理方式 从@SpringBootApplication注解说起 @SpringBootApplication组合注解说明 @Target(ElementType.TYPE) @ ...
- Spring Boot 自动装配原理
本文已经收录到Github仓库,该仓库包含计算机基础.Java核心知识点.多线程.JVM.常见框架.分布式.微服务.设计模式.架构等核心知识点,欢迎star~ Github地址:https://git ...
- Spring Boot: SpringFox Swagger原理解析及简单实用
文章目录 简介 一.Swagger简单使用 二.Swagger原理 三.Swagger架构分析及组成 其他 简介 API的全称是应用编程接口(Application Programming Inter ...
- Spring/Spring MVC/Spring Boot自动装配机制介绍
- springboot 自动装配_Spring Boot 自动装配流程
Spring Boot 自动装配流程 本文以 mybatis-spring-boot-starter 为例简单分析 Spring Boot 的自动装配流程. Spring Boot 发现自动配置类 这 ...
- 【Spring Boot实战】源码解析Spring Boot自动配置原理
一.简介 Spring致力于让Java开发更简单,SpringBoot致力于让使用Spring进行Java开发更简单,SpringCloud致力于基于SpringBoot构建微服务生态圈,让微服务开发 ...
- Spring Boot自动配置与Spring 条件化配置
SpringBoot自动配置 SpringBoot的自动配置是一个运行时(应用程序启动时)的过程,简化开发时间,无需浪费时间讨论具体的Spring配置,只需考虑如何利用SpringBoot的自动配置即 ...
最新文章
- Jeff Dean:我们写了一份「稀疏模型设计指南」,请查收
- 重磅!IJCAI 2020 好狠,超四成论文未经全文评审就out!被拒作者:一脸懵逼,反馈意见呢?...
- [MAC OS] 常用工具
- Linux下编写选择排序(C语言)
- Codeforces 85D Sum of Medians
- 四大对象是什么时候创建的?
- React中ref的使用方法
- TCP/IP协议-1
- 函数hook注意事项
- python提取图片文字视频教学_用Python提取视频中的图片
- c语言中建一个文件的语法,C语言语法介绍_文件.ppt
- python修改pdf文件大小,python读pdf文件字体大小_用Python读取pdf文件
- 监听返回app_基于 Redis 消息队列实现 Laravel 事件监听及底层源码探究
- swift在线天气预报案例教程
- 将QQ语音的slk格式转化为wma
- [随心译]2017.8.5-你家毛茸茸的宠物的荤粮正在加速气候变化
- Word文档人民币符号怎么打出来
- uniapp定位和选择城市
- 分析APP的安装流程 API29
- 可视化脑洞|1896年以来奥运奖牌数据背后的故事
热门文章
- pebble刷android wear,Pebble智能手表刷官方中文固件教程
- Java语言的出现背景、主要特点、发展历程以及Java技术的应用
- 使用Pygame制作2048小游戏
- 正点原子STM32-串口中断服务函数USART1_IRQHandler关于USART_RX_STA的学习笔记
- STM32串口读取一帧数据USART_IT_IDLE
- 文法和语言的基本知识
- 服务器安装linux亮机卡,井蛙杂谈——HQPlayer升频折腾手记——108楼更新3700x,9700K完美7EC配置方案...
- P5:用统一的NLP框架建模推荐系统问题
- SpringBoot第二十三篇:安全性之Spring Security
- 中国私营企业特点有哪些