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的项目骨架.接下来我们简单分析 ...
随机推荐
- <image>的src属性的使用
刚接触前端不久.怎么用image显示图片是个问题,怎么使用数据流还是base64呢?小小的研究一下 <image src="url"> 1.接口返回数据流,src可以直 ...
- JavaScript事件兼容性写法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- R_Studio(学生成绩)使用主成分分析实现属性规约
对11_1_4.csv成绩表进行主成分分析处理 setwd('D:\\data') list.files() #读取数据 dat=read.csv(file="11_1_4.csv" ...
- Unity3D_(游戏)2D简单游戏制作过程:捕获高空掉落保龄球
游戏介绍:通过鼠标的左右移动,可以控制帽子的移动,当帽子接到下落的保龄球时,会出现火花效果.没有接到保龄球时,保龄球落到草地上,过10S后会自动消失. 实现效果: 素材+Unity3D源代码:传送 ...
- docker删除容器再删除镜像
1. 查询镜像 docker images 现在想删除第一个,ID为 99f85991949f 的镜像. docker rmi ID 从上面看出,需要先停到ID为 67*** 的容器. 2. 查询容 ...
- ionic1使用imagepicker在安卓手机上闪退问题
在上一篇文章中,提到了如何在ionic1中使用imagepicker插件,并且实现该插件显示中文(汉化)问题有兴趣可以看看:ionic1使用ImagePicker插件并且显示中文(汉化) 1.这次要解 ...
- 自动化部署脚本--linux执行sh脚本
自动化部署脚本文件目录: 运行主程序:./install.sh #!/bin/bash SCRIPTPATH=$(cd "$(dirname "$0")"; p ...
- gdb调试时忽略SIGPIPE 等信号
GDB调试网络程序时,会遇到SIGPIPE信息,默认GDB会把程序停下来,即使程序使用signal(SIGPIPE, SIG_IGN);来忽略信号.用handle命令设置一下缺省的signal的处理行 ...
- 191107Django的Cookie和Session
Cookie的使用 from django.shortcuts import render,redirect def login(request): print("1",reque ...
- 利用 IntelliJ IDEA 进行代码对比的方法
Sometimes,我们会有这样的需求,即:想对比出两个不同版本代码的区别.如何实现? 第 1 种:如果我们是从 SVN 检出的项目,并且想比较本地代码与从 SVN 检出时的代码相比都有那些区别,可以 ...