SpringBoot就是一个javaweb的开发框架,和SpringMVC类似。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。
优势:
为所有Spring开发者更快的入门
开箱即用,提供各种默认配置来简化项目配置
内嵌式容器简化Web项目
没有冗余代码生成和XML配置的要求
一、SpringBoot运行原理
1. pom.xml文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>及其父依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;
以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了
及启动器:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
springboot-boot-starter-xxx:就是spring-boot的场景启动器
spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;
SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们也可以自己自定义 starter;
2. 主启动类
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}1)@SpringBootApplication注解(重要)
@SpringBootApplication标注在某个类上说明这个类是SpringBoot的主配置类(自定义配置可以写在@Configeration) , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用,在启动过程中:
SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值;
将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中(spring.factories);
它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;
可以给注解@SpringBootApplication或@Configuration设置参数proxyBeanMethods:
@SpringBootApplication(proxyBeanMethods = false) or @Configuration(proxyBeanMethods = false)
当proxyBeanMethods为true时(默认):为full模式,每次调用bean会先检查容器中是否有该bean,若有,直接从容器中拿,所以对象是单例的。
当proxyBeanMethods为false时:为lite模式,每次调用bean,不会检查容器有没有,都会新建一个。
最佳实践:
当配置类中,组件没有依赖关系。那么使用lite模式,加速容器启动,减少判断。
当配置类中,组件有依赖,方法调用会得到之前的组件,就使用full模式。
2)SpringApplication.run()(不重要)
这个类主要做了以下四件事情:
1. 推断应用的类型是普通的项目还是Web项目
2. 查找并加载所有可用初始化器 , 设置到initializers属性中
3. 找出所有的应用程序监听器,设置到listeners属性中
4. 推断并设置main方法的定义类,找到运行的主类
3. 底层注解前置
1. @ConditionalOnXXX:加在类上,用于条件注入,如果满足XXX那么对组件进行注入。
2. @Bean:加在方法上。用于告诉方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。 产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
3. @Configuration:加在类上表明该类是一个自定义配置类,与xml配置文件作用相同。其中可自定义加bean注解的方法。也可以设置lite或full模式。
4. @Import({xxx.class}):写在容器的组件上(可以是@Bean上也可以是类组件上),用于给容器中自动创建xxx类型的组件。(可来自于自定义的class也可以来自于外部导入的class)。倒入的组件名称为全限定类名。
TODO:...............
二、SpringBoot自动配置原理
以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理,源码如下:
//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration
//启动指定类的ConfigurationProperties功能;
//进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
//并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({HttpProperties.class})
//Spring底层@Conditional注解
//根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
//这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(
type = Type.SERVLET
)
//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({CharacterEncodingFilter.class})
//判断配置文件中是否存在某个配置:spring.http.encoding.enabled;
//如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
//他已经和SpringBoot的配置文件映射了
private final Encoding properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}
//给容器中添加一个组件,这个组件的某些值需要从properties中获取
@Bean
@ConditionalOnMissingBean //判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
}
//。。。。。。。
}结论:
1、SpringBoot启动会加载大量的自动配置类
2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
Tips:SpringBoot推荐使用.yaml来配置,与properties不同在于yml除了存储键值对外还可以存储对象。