Taobao side: "talk about spring boot automatic assembly principle?"

JavaGuide 2021-01-21 11:06:25
taobao talk spring boot automatic


This article has been included in Github 95k+ Star Of Java project JavaGuide .JavaGuide Project address : https://github.com/Snailclimb... .

author :Miki-byte-1024 & Snailclimb

Every time I ask Spring Boot, Interviewers like to ask this question very much :“ Tell me SpringBoot Principle of automatic assembly ?”.

I think we can answer it from the following aspects :

  1. What is? SpringBoot Automatic assembly ?
  2. SpringBoot How to realize automatic assembly ? How to achieve on-demand loading ?
  3. How to achieve a Starter?

The space problem , This article doesn't go deep , Friends can also use it directly debug The way to see SpringBoot Automatic assembly part of the source code .

Preface

Have used Spring Little buddy , There must be someone XML Fear of configuration rule . Even if Spring Annotation based configuration is introduced later , We're opening up some Spring Features or the introduction of third-party dependencies , Still need to use XML or Java Make explicit configuration .

for instance . No, Spring Boot When , Let's write a RestFul Web service , First of all, you need to configure as follows .

@Configuration
public class RESTConfiguration
{
@Bean
public View jsonTemplate() {
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setPrettyPrint(true);
return view;
}
@Bean
public ViewResolver viewResolver() {
return new BeanNameViewResolver();
}
}

spring-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context/ http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc/ http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="com.howtodoinjava.demo" />
<mvc:annotation-driven />
<!-- JSON Support -->
<bean name="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonTemplate" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView"/>
</beans>

however ,Spring Boot project , We just need to add dependency , No need to configure , By starting the following main The method can .

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

also , We go through Spring Boot Global configuration file for application.properties or application.yml You can set the project, such as changing the port number , To configure JPA Properties and so on .

Why? Spring Boot It's so sour to use ? This benefits from its automatic assembly . Automatic assembly can be said to be Spring Boot At the heart of , So what is automatic assembly ?

What is? SpringBoot Automatic assembly ?

Now when we talk about automatic assembly , It's usually with Spring Boot Connect . however , actually Spring Framework This function has been realized for a long time .Spring Boot Just on the basis of it , adopt SPI The way , Further optimization has been made .

SpringBoot Defines a set of interface specifications , This set of regulations :SpringBoot External references are scanned at startup jar In bag META-INF/spring.factories file , Load the type information configured in the file into Spring Containers ( It's about JVM Class loading mechanism and Spring Container knowledge of ), And perform the various operations defined in the class . For external jar Come on , Just follow SpringBoot The standard of definition , You can put your own functions into the SpringBoot.

No, Spring Boot Under the circumstances , If we need to introduce third-party dependencies , Manual configuration required , Very trouble . however ,Spring Boot in , Let's just introduce a starter that will do . For example, you want to use... In a project redis Words , Introduce the corresponding... Directly into the project starter that will do .

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

introduce starter after , We can use the functions provided by third-party components with a few annotations and simple configuration .

in my opinion , Automatic assembly can be simply understood as : Through annotations or some simple configuration, you can find the Spring Boot With the help of .

SpringBoot How to realize automatic assembly ?

Let's take a look first SpringBoot Core notes for SpringBootApplication .

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
<1.>@SpringBootConfiguration
<2.>@ComponentScan
<3.>@EnableAutoConfiguration
public @interface SpringBootApplication {
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // In fact, it is also a configuration class
public @interface SpringBootConfiguration {
}

Maybe we can put @SpringBootApplication See as @Configuration@EnableAutoConfiguration@ComponentScan Set of annotations . according to SpringBoot Official website , The function of these three notes is :

  • @EnableAutoConfiguration: Enable SpringBoot Automatic configuration mechanism
  • @Configuration: Allow additional... To be registered in context bean Or import other configuration classes
  • @ComponentScan: Scan by @Component (@Service,@Controller) Annotated bean, By default, annotations scan all classes in the package where the startup class is located , You can customize not to scan some bean. As shown in the figure below , The container will exclude TypeExcludeFilter and AutoConfigurationExcludeFilter.

@EnableAutoConfiguration It is an important annotation to realize automatic assembly , Let's start with this note .

@EnableAutoConfiguration: Realize the core annotation of automatic assembly

EnableAutoConfiguration It's just a simple comment , The core function of automatic assembly is realized through AutoConfigurationImportSelector class .

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage // effect : take main The desired components under the package are registered in the container
@Import({AutoConfigurationImportSelector.class}) // Load auto assembly class xxxAutoconfiguration
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}

Now let's focus on AutoConfigurationImportSelector What does class do ?

AutoConfigurationImportSelector: Load auto assembly class

AutoConfigurationImportSelector The inheritance system of class is as follows :

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
}
public interface DeferredImportSelector extends ImportSelector {
}
public interface ImportSelector {
String[] selectImports(AnnotationMetadata var1);
}

It can be seen that ,AutoConfigurationImportSelector Class implements the ImportSelector Interface , It also implements the selectImports Method , This method is mainly used for Get the fully qualified class names of all qualified classes , These classes need to be loaded into IoC In the container .

private static final String[] NO_IMPORTS = new String[0];
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// <1>. Judge whether the automatic assembly switch is on
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
//<2>. Get all that need to be assembled bean
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}

Here we need to focus on getAutoConfigurationEntry() Method , This method is mainly responsible for loading the auto configuration class .

The method call chain is as follows :

Now we combine getAutoConfigurationEntry() Source code to analyze in detail :

private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();
AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
//<1>.
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
//<2>.
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
//<3>.
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
//<4>.
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}

The first 1 Step :

Judge whether the automatic assembly switch is on . Default spring.boot.enableautoconfiguration=true, Can be found in application.properties or application.yml Set in

The first 2 Step

Used to get EnableAutoConfiguration In the annotations exclude and excludeName.

The first 3 Step

Get all the configuration classes that need to be automatically assembled , Read META-INF/spring.factories

spring-boot/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories

As can be seen from the figure below, the configuration content of this file has been read by us .XXXAutoConfiguration The function of is to load components on demand .

It's not just this dependence META-INF/spring.factories Read to , all Spring Boot Starter Under the META-INF/spring.factories Will be read to .

therefore , You can see clearly , druid Database connection pool Spring Boot Starter It was created. META-INF/spring.factories file .

If , We're going to create one ourselves Spring Boot Starter, This step is essential .

The first 4 Step

Maybe the interviewer will ask you :“spring.factories So many configurations in , Do I have to load all of them every time I start ?”.

Obviously , This is unrealistic . We debug Go back and you'll find ,configurations The value of is smaller .

because , This step has gone through a screening ,@ConditionalOnXXX All the conditions in are met , That kind of thing works .

@Configuration
// Check the related classes :RabbitTemplate and Channel Whether there is
// Only when it exists will it be loaded
@ConditionalOnClass({ RabbitTemplate.class, Channel.class })
@EnableConfigurationProperties(RabbitProperties.class)
@Import(RabbitAnnotationDrivenConfiguration.class)
public class RabbitAutoConfiguration {
}

Interested in children's shoes can learn more about Spring Boot Notes on the conditions provided

  • @ConditionalOnBean: When there is a designation in the container Bean Under the condition of
  • @ConditionalOnMissingBean: When there is no designation in the container Bean Under the circumstances
  • @ConditionalOnSingleCandidate: When specifying Bean There's only one in the container , Or even though there are more than one, but specify the preferred Bean
  • @ConditionalOnClass: When there is a specified class in the class path
  • @ConditionalOnMissingClass: When there is no specified class in the classpath
  • @ConditionalOnProperty: Whether the specified property has the specified value
  • @ConditionalOnResource: Whether the class path has the specified value
  • @ConditionalOnExpression: be based on SpEL Expression as a condition of judgment
  • @ConditionalOnJava: be based on Java Version as a condition of judgment
  • @ConditionalOnJndi: stay JNDI Under the condition of existence, the difference is in the specified position
  • @ConditionalOnNotWebApplication: The current project is not Web Under project conditions
  • @ConditionalOnWebApplication: The current project is Web term Under the condition of objective

How to achieve a Starter

Saying without practicing the fake trick , Now let's have one starter, Implement custom thread pool

First step , establish threadpool-spring-boot-starter engineering

The second step , introduce Spring Boot Related dependencies

The third step , establish ThreadPoolAutoConfiguration

Step four , stay threadpool-spring-boot-starter engineering resources Package created under META-INF/spring.factories file

Finally, the new project introduces threadpool-spring-boot-starter

The test passed !!!

summary

Spring Boot adopt @EnableAutoConfiguration Turn on automatic assembly , adopt SpringFactoriesLoader Final load META-INF/spring.factories The automatic configuration class in realizes automatic assembly , Automatic configuration of classes is actually through @Conditional Configuration classes loaded on demand , To make it work, we have to introduce spring-boot-starter-xxx Package implementation depends on

End of article

I am a Guide Brother , One Java The backend development , A little bit of the front end , Free youth . See you next time ! Wechat search “JavaGuide” reply “ Interview shock ” Get what I've arranged 4 Original PDF

版权声明
本文为[JavaGuide]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210121110100196N.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云