spring boot-3.原理探究
新建的项目结构如下图:

1.POM 文件
项目会默认依赖 spring-boot-starter-parent 项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
这个parent项目又依赖下面
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
spring-boot-dependencies 这个依赖里面定义spring boot 真正依赖的jar包和适配的版本号,所以后面的依赖就不用定义版本号,spring boot 已经自动适配了合适的版本。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
同时还依赖了spring-boot-starter-*,spring boot 官方文档 https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#using-boot-dependency-management ,13.5 章节介绍了这些Satrter ,根据文档,这些starter 是spring boot 根据实际应用场景封装的一系列场景启动器,可以为我们提供相应场景的一站式服务,比如我们需要data-jpa支持,我们只要导入spring-boot-starter-data-jpa 这个启动器即可,spring boot 会导入相应jar包,并自动配置相应的场景。
pom文件中同时还有关于 Spring Boot Maven 插件,它可以将项目打成单独的jar包,通过java -jar 命令已独立的应用形式来运行。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.启动类
项目类路径下有一个名称为***Application 的类
@SpringBootApplication
public class SpringbootAutoconfigApplication { public static void main(String[] args) {
SpringApplication.run(SpringbootAutoconfigApplication.class, args);
}
}
@SpringBootApplication 这个注解的意思是:将当前类标志为主程序类,程序的运行入口为这个类。这个注解是多个注解的组合
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
其中最重要的@EnableAutoConfiguration这个注解的意思是:开启spring boot 自动配置功能,然后通过AutoConfigurationImportSelector 来选择应该自动将哪些自动配置导入到容器中,要导入的自动配置组件都在META-INF/spring-autoconfigure-metadata.properties这个配置文件中有相应配置。在spring-boot-autoconfigure-2.0.4.RELEASE.jar 里面有所有Starter自动配置,在相应的自动配置类里面可以看到配置的生效条件,和我们可以自己配哪些属性。以dao的自动配置为例
@ConditionalOnClass(PersistenceExceptionTranslationPostProcessor.class)
public class PersistenceExceptionTranslationAutoConfiguration { @Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.dao.exceptiontranslation", name = "enabled", matchIfMissing = true)
public static PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(
Environment environment) {
PersistenceExceptionTranslationPostProcessor postProcessor = new PersistenceExceptionTranslationPostProcessor();
boolean proxyTargetClass = environment.getProperty(
"spring.aop.proxy-target-class", Boolean.class, Boolean.TRUE);
postProcessor.setProxyTargetClass(proxyTargetClass);
return postProcessor;
} }
@ConditionalOnClass 类路径下有 PersistenceExceptionTranslationPostProcessor的class时生效
@ConditionalOnMissingBean 意思是没有这个组件的时候生效,我们可以配置的内容是 spring.dao.exceptiontranslation,没有配置的情况下的默认值是true。
官方文档的15至16介绍了关于自动配置的其他内容。我们可以自己编写自定义的配置和禁用部分自动配置。如何编写自己的自动以类呢?
官方文档是这么说的,我们可以不用将所有 的配置放在,我们只需要自己编写配置类,并让它加载进容器中就可以了。比如
@Configuration
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
//@ComponentScan(basePackages={"xx.xx.xx.MyConfig,xx.xx.xx.MyAnotherConfig"})
public class Application { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
} }
或者 在Application 中已@Bean的注解来创建一个组件,并将组件加入到容器中
@Import注解的意思是将类作为组件加载到容器中
@ComponentScan 注解的意思的将路径的中的类作为组件天剑到容器中。由于Application 默认扫描的是当前所在目录及其下级目录的组件,所以一般情况下不需要声明扫包的路径,但是如有其它第三方的的包可以用这种方式将组件添加到容器中。
如何禁用自动配置呢?官方文档的16.2章节有 说明。比如下面:
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*; @Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
自定义一个Configuration,通过exclude排除不需要自动配置的组件。然后再主程序中将这个配置类添加到容器中即可。
关于这条件注解分为以下几类:
| 注解 | 处理类 | 处理逻辑 | 实例 | 
|---|---|---|---|
| @Conditional | OnBeanCondition | 当给定的类型、类名、注解、昵称在beanFactory中存在时返回true.各类型间是or的关系 | @ConditionalOnBean (CacheManager.class) | 
| @ConditionalOnSingleCandidate | OnBeanCondition | 当给定类型的bean存在并且指定为Primary的给定类型存在时,返回true | @ConditionalOnSingleCandidate (DataSource.class) | 
| @ConditionalOnMissingBean | OnBeanCondition | 当给定的类型、类名、注解、昵称在beanFactory中不存在时返回true.各类型间是or的关系 | @ConditionalOnMissingBean | 
| @ConditionalOnClass | OnClassCondition | 当给定的类型、类名在类路径上存在时返回true,各类型间是and的关系 | @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class }) | 
| @ ConditionalOnMissingClass | OnClassCondition | 当给定的类名在类路径上不存在时返回true,各类型间是and的关系 | @ConditionalOnMissingClass(“org.thymeleaf.templatemode.TemplateMode”) | 
| @ConditionalOnCloudPlatform | OnCloudPlatformCondition | 当所配置的CloudPlatform为激活时返回true | @ConditionalOnCloudPlatform(CloudPlatform.CLOUD_FOUNDRY) | 
| @ConditionalOnExpression | OnExpressionCondition | 如果该表达式返回true则代表匹配,否则返回不匹配 | @ConditionalOnExpression(“true”) | 
| @ConditionalOnJava | OnJavaCondition | 运行时的java版本号是否包含给定的版本号.如果包含,返回匹配,否则,返回不匹配 | @ConditionalOnJava(ConditionalOnJava.JavaVersion.EIGHT) | 
| @ConditionalOnJndi | OnJndiCondition | 给定的jndi的Location 必须存在一个.否则,返回不匹配 | @ConditionalOnJndi({ “java:comp/TransactionManager”}) | 
| @ConditionalOnNotWebApplication | OnWebApplicationCondition | 不在web环境时返回匹配 | @ConditionalOnNotWebApplication | 
| @ConditionalOnWebApplication | OnWebApplicationCondition | 不在web环境时返回匹配 | @ConditionalOnWebApplication | 
| @ConditionalOnProperty | OnPropertyCondition | 配置的属性存在时匹配 | @ConditionalOnProperty(prefix = “spring.aop”, name = “auto”, havingValue = “true”, matchIfMissing = true) | 
| @ConditionalOnResource | OnResourceCondition | 指定的资源必须存在,否则返回不匹配 | @ConditionalOnResource(resources = “classpath:META-INF/build-info.properties”) | 
spring boot-3.原理探究的更多相关文章
- Spring Boot 运作原理
		Spring Boot 运作原理 1.Spring Boot 简介 SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了 ... 
- Spring Boot启动原理解析
		Spring Boot启动原理解析http://www.cnblogs.com/moonandstar08/p/6550758.html 前言 前面几章我们见识了SpringBoot为我们做的自动配置 ... 
- Spring Boot运行原理
		概述 本文主要写了下Spring Boot运行原理,还有一个小例子. Spring4.x提供了基于条件来配置Bean的能力,而Spring Boot的实现也是基于这一原理的. Spring Boot关 ... 
- spring boot启动原理步骤分析
		spring boot最重要的三个文件:1.启动类 2.pom.xml 3.application.yml配置文件 一.启动类->main方法 spring boot启动原理步骤分析 1.spr ... 
- Spring Boot核心原理
		Spring Boot核心原理 spring-boot-starter-xxx 方便开发和配置 1.没有depoy setup tomcat 2.xml文件里面的没有没有了 @SpringBootA ... 
- Spring Boot 启动原理分析
		https://yq.aliyun.com/articles/6056 转 在spring boot里,很吸引人的一个特性是可以直接把应用打包成为一个jar/war,然后这个jar/war是可以直接启 ... 
- Spring Boot 运行原理
		Spring Boot并没有任何新的技术,全都是基于Spring4提供的技术,用优秀的设计,为Web开发提供了一套新的方式. 在HelloWorld中,我们没有进行任何显示的配置,但是程序还是运行起来 ... 
- Spring boot运行原理-自定义自动配置类
		在前面SpringBoot的文章中介绍了SpringBoot的基本配置,今天我们将给大家讲一讲SpringBoot的运行原理,然后根据原理我们自定义一个starter pom. 本章对于后续继续学习S ... 
- spring boot 启动原理详细解析
		我们开发任何一个Spring Boot项目,都会用到如下的启动类 1 @SpringBootApplication 2 public class Application { 3 public stat ... 
- Spring Boot高频面试题:Spring Boot执行原理
		之前一篇文章Spring Boot快速入门文章中,我们已经体会到Spring Boot的神器,不再像之前Spring那样需要繁琐的XML,甚至几秒钟就能搭建出Spring的项目骨架.接下来我们简单分析 ... 
随机推荐
- wx小程序知识点(五)
			五.双向绑定和 vue 的区别 ① vue 中实现双向绑定只需要修改 this.data var vm = new Vue({ el: '#example', data: { message: 'He ... 
- codevs 2602 最短路径问题x
			题目描述 Description 平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间.其中的一些点之间有连线.若有连线,则表示 ... 
- Springboot 解决跨域请求
			Cors处理 跨域请求 细粒度 直接在controller层上 添加@CrossOrigin注解 @PostMapping("/") @CrossOrigin(value = &q ... 
- Jmeter -- 入门,基础操作
			1. 添加线程组 设置线程组参数(线程数.准备时长.循环次数等): a)线程数:虚拟用户数.一个虚拟用户占用一个进程或线程.设置多少虚拟用户数在这里也就是设置多少个线程数. b)Ramp-Up Per ... 
- 品 SpringBootApplication 注解源码
			@SpringBootApplication 由以下三个注解构成: @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan 一:@ ... 
- C++类的默认成员函数
			成员函数隐含this指针参数: 每成员函数一个隐式的指针形参(构造函数除外): 对象在调用成员函数时,编译器会将对象的地址传递给this指针: 1.构造函数(需用一个公有成员函数对私有的成员变量进行初 ... 
- JavaScript 普通声明式函数
			1.为什么需要函数 实现代码的复用.存在函数提升,且会在变量提升的上面; 2.函数的创建 js中函数语法: function 函数名(形参){ //函数体 } 调用时:函数名(形参) 注: (1) 形 ... 
- LeetCode 14. 最长公共前缀(Longest Common Prefix)
			题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow ... 
- java多线程系列3:悲观锁和乐观锁
			1.悲观锁和乐观锁的基本概念 悲观锁: 总是认为当前想要获取的资源存在竞争(很悲观的想法),因此获取资源后会立刻加锁,于是其他线程想要获取该资源的时候就会一直阻塞直到能够获取到锁: 在传统的关系型数据 ... 
- Windows10无法打开NVIDA控制面板
			今天开机,突然发现NVIDA控制面板无法打开,在桌面右键启动nView Desktop Manager,点击启动,发现也无法启动控制面板,并且提示[您当前未使用连接到nvidia gpu的显示器].查 ... 
