Springboot基本原理(二)
1. 简化依赖原理分析
1.1 spring-boot-starter-parent
点击pom.xml文件中的springboot-starter-parent,跳转到了springboot-starter-parent的pom.xml,xml配置如下(这里只截了部分重点配置)
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.2.1.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath> </parent>
点击pom.xml中的spring-boot-starter-dependencies,跳转到了spring-boot-starter-dependencies的pom.xml,配置如下(部分重要配置):
<properties> <activemq.version>5.15.10</activemq.version> <antlr2.version>2.7.7</antlr2.version> <appengine-sdk.version>1.9.76</appengine-sdk.version> <artemis.version>2.10.1</artemis.version> <aspectj.version>1.9.4</aspectj.version> <assertj.version>3.13.2</assertj.version> <atomikos.version>4.0.6</atomikos.version> <awaitility.version>4.0.1</awaitility.version> <bitronix.version>2.1.4</bitronix.version> <build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version> <byte-buddy.version>1.10.2</byte-buddy.version> <caffeine.version>2.8.0</caffeine.version> <cassandra-driver.version>3.7.2</cassandra-driver.version> <classmate.version>1.5.1</classmate.version> <commons-codec.version>1.13</commons-codec.version> .................... </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>2.2.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <version>2.2.1.RELEASE</version> </dependency> .................... </dependencyManagement> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.johnzon</groupId> <artifactId>johnzon-maven-plugin</artifactId> <version>${johnzon.version}</version> </plugin> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> </plugin> .................... </plugins> </pluginManagement> </build>
从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件已经定义好,所以我们的springboot工程继承springboot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。
1.2 spring-boot-starter-web
点击pom.xml中的spring-boot-starter-web,跳转到spring-boot-starter-web的pom.xml,配置如下:
<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starters</artifactId> <version>2.2.1.RELEASE</version> </parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.1.RELEASE</version> <name>Spring Boot Web Starter</name> <description>Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container</description> <url>https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-web</url> <organization> <name>Pivotal Software, Inc.</name> <url>https://spring.io</url> </organization> <licenses> <license> <name>Apache License, Version 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0</url> </license> </licenses> <developers> <developer> <name>Pivotal</name> <email>info@pivotal.io</email> <organization>Pivotal Software, Inc.</organization> <organizationUrl>https://www.spring.io</organizationUrl> </developer> </developers> <scm> <connection>scm:git:git://github.com/spring-projects/spring-boot.git</connection> <developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-boot.git</developerConnection> <url>https://github.com/spring-projects/spring-boot</url> </scm> <issueManagement> <system>Github</system> <url>https://github.com/spring-projects/spring-boot/issues</url> </issueManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.2.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> <version>2.2.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.2.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>2.2.1.RELEASE</version> <scope>compile</scope> <exclusions> <exclusion> <artifactId>tomcat-embed-el</artifactId> <groupId>org.apache.tomcat.embed</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.1.RELEASE</version> <scope>compile</scope> </dependency> </dependencies> </project>
从spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”。这样我们的工程只要依赖了spring-boot-starter-web,就可以进行web开发,同样体现了依赖传递的作用。
2. 自动配置原理解析
点击启动类上的@SpringBootApplication注解,@SpringBootApplication注解的源码如下(部分内容):
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration // 等同于@Configuration,即标注该类是Spring的一个配置类 @EnableAutoConfiguration // SpringBoot自动配置功能开启 @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { @AliasFor( annotation = EnableAutoConfiguration.class ) Class<?>[] exclude() default {}; ... ... ... }
点击查看注解@EnableAutoConfiguration
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }
其中,@Import(AutoConfigurationImportSelector.class) 导入了AutoConfigurationImportSelector类,点击查看AutoConfigurationImportSelector源码
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()); } } ... ... ... 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,这个外部文件中有很多自动配置的类。
spring.properties文件中有关自动配置的配置信息如下(只截取部分用来说明):
上面的配置文件中存在大量的以Configuration为结尾的类名称,这些都是存有自动配置信息的类。SpringApplication在获取这些类名后再加载。
以ServletWebServerFactoryAutoConfiguration为例分析:
@Configuration( proxyBeanMethods = false ) @AutoConfigureOrder(-2147483648) @ConditionalOnClass({ServletRequest.class}) @ConditionalOnWebApplication( type = Type.SERVLET ) @EnableConfigurationProperties({ServerProperties.class}) // 加载ServerProperties服务器配置属性类 @Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class}) public class ServletWebServerFactoryAutoConfiguration { ... ... ... }
进入ServerProperties.class源码如下:
@ConfigurationProperties( prefix = "server", ignoreUnknownFields = true ) public class ServerProperties { private Integer port; private InetAddress address; ... ... ... }
prefix = "server" 表示SpringBoot配置文件中的前缀,SpringBoot会将配置文件中以server开头的属性映射到该类的字段中。映射关系如下:
原文地址:https://www.cnblogs.com/willncy/p/11873166.html
- Go语言异步服务器框架原理和实现
- nyoj------布线问题(kruscal+求最小值)
- nyoj-----127星际之门(一)
- nyoj------20吝啬的国度
- HDUOJ-------2493Timer(数学 2008北京现场赛H题)
- go sync.Mutex 设计思想与演化过程 (一)
- HDUOJ--------A simple stone game(尼姆博弈扩展)(2008北京现场赛A题)
- HDUOJ----2485 Destroying the bus stations(2008北京现场赛A题)
- Go语言实践:从新手入门到上线真实的小型服务所遇到的那些坑
- Node.js真的无所不能?那些不适用的应用领域分析
- hdu-----2491Priest John's Busiest Day(2008 北京现场赛G)
- nyoj------79拦截导弹
- HDUOJ-------2719The Seven Percent Solution
- Golang记录、计算函数执行耗时、运行时间的一个简单方法
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- MySQL-1
- 并发编程之Atomic&Unsafe魔法类详解
- Hexo+Next7.X 博客美化教程合集
- 波士顿房价预测 - 最简单入门机器学习 - Jupyter
- 机器学习竞赛分享:NFL大数据碗(上篇)
- 大文件分割、命名脚本 - Python
- adb常用命令总结
- Cypress执行测试并邮寄发送测试报告
- 重拾前端技能为你的职业前程保驾护航
- 检查图片是否损坏、图片后缀是否与实际图片类型对应 - Python
- 规则引擎 - drools 使用讲解(简单版) - Java
- Python奇技淫巧 - 持续更新中....
- 150+行Python代码实现带界面的数独游戏
- Python实现十大经典排序算法
- 140行Python代码实现Flippy Bird