文章目录

  • 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演示相关推荐

  1. Spring Boot自动装配原理详解

    目录 1.环境和依赖 1.1.spring boot版本 1.2.依赖管理 2.自动装配 2.1.流程概述 2.2.三大步前的准备工作 2.2.1.注解入口 2.2.2.获取所有配置类 2.3.获取过 ...

  2. Spring Boot 自动装配的原理

    在Spring Boot中,不得不说的一个点是自动装配,它是Starter的基础,也是Spring Boot的核心,那么什么叫自动装配呢?或者说什么叫装配呢? 简单来说,就是自动将Bean装配到IoC ...

  3. Spring Boot - 自动装配中的不可忽视的@Import

    文章目录 Pre 四种处理方式 从@SpringBootApplication注解说起 @SpringBootApplication组合注解说明 @Target(ElementType.TYPE) @ ...

  4. Spring Boot 自动装配原理

    本文已经收录到Github仓库,该仓库包含计算机基础.Java核心知识点.多线程.JVM.常见框架.分布式.微服务.设计模式.架构等核心知识点,欢迎star~ Github地址:https://git ...

  5. Spring Boot: SpringFox Swagger原理解析及简单实用

    文章目录 简介 一.Swagger简单使用 二.Swagger原理 三.Swagger架构分析及组成 其他 简介 API的全称是应用编程接口(Application Programming Inter ...

  6. Spring/Spring MVC/Spring Boot自动装配机制介绍

  7. springboot 自动装配_Spring Boot 自动装配流程

    Spring Boot 自动装配流程 本文以 mybatis-spring-boot-starter 为例简单分析 Spring Boot 的自动装配流程. Spring Boot 发现自动配置类 这 ...

  8. 【Spring Boot实战】源码解析Spring Boot自动配置原理

    一.简介 Spring致力于让Java开发更简单,SpringBoot致力于让使用Spring进行Java开发更简单,SpringCloud致力于基于SpringBoot构建微服务生态圈,让微服务开发 ...

  9. Spring Boot自动配置与Spring 条件化配置

    SpringBoot自动配置 SpringBoot的自动配置是一个运行时(应用程序启动时)的过程,简化开发时间,无需浪费时间讨论具体的Spring配置,只需考虑如何利用SpringBoot的自动配置即 ...

最新文章

  1. Jeff Dean:我们写了一份「稀疏模型设计指南」,请查收
  2. 重磅!IJCAI 2020 好狠,超四成论文未经全文评审就out!被拒作者:一脸懵逼,反馈意见呢?...
  3. [MAC OS] 常用工具
  4. Linux下编写选择排序(C语言)
  5. Codeforces 85D Sum of Medians
  6. 四大对象是什么时候创建的?
  7. React中ref的使用方法
  8. TCP/IP协议-1
  9. 函数hook注意事项
  10. python提取图片文字视频教学_用Python提取视频中的图片
  11. c语言中建一个文件的语法,C语言语法介绍_文件.ppt
  12. python修改pdf文件大小,python读pdf文件字体大小_用Python读取pdf文件
  13. 监听返回app_基于 Redis 消息队列实现 Laravel 事件监听及底层源码探究
  14. swift在线天气预报案例教程
  15. 将QQ语音的slk格式转化为wma
  16. [随心译]2017.8.5-你家毛茸茸的宠物的荤粮正在加速气候变化
  17. Word文档人民币符号怎么打出来
  18. uniapp定位和选择城市
  19. 分析APP的安装流程 API29
  20. 可视化脑洞|1896年以来奥运奖牌数据背后的故事

热门文章

  1. pebble刷android wear,Pebble智能手表刷官方中文固件教程
  2. Java语言的出现背景、主要特点、发展历程以及Java技术的应用
  3. 使用Pygame制作2048小游戏
  4. 正点原子STM32-串口中断服务函数USART1_IRQHandler关于USART_RX_STA的学习笔记
  5. STM32串口读取一帧数据USART_IT_IDLE
  6. 文法和语言的基本知识
  7. 服务器安装linux亮机卡,井蛙杂谈——HQPlayer升频折腾手记——108楼更新3700x,9700K完美7EC配置方案...
  8. P5:用统一的NLP框架建模推荐系统问题
  9. SpringBoot第二十三篇:安全性之Spring Security
  10. 中国私营企业特点有哪些