SpringBoot

220 阅读6分钟

SpringBoot

  • 自动配置
  • 起步依赖 starter
  • actuator 监控
  • 命令行

自动配置

使用

@EnableAutoConfiguration注解 ,@SpringBootApplication已经包含此注解

启动自动配置,可以通过exclude进行排除,手动配置

spring.factories配置文件进行自动配置

自动配置的原理

根据条件判断是否需要某些自动配置

例如依赖了H2的jar,包含H2的对象,又没有配置类,就自动加载默认配置

注解举例:

@Conditional,@ConditionalOnClass, @ConditionalOnBean, @ConditionalOnPropertiy(enable = true ),@onMissingBean(xx.class)

注解原理:BeanFactoryPostProcessor查找bean的定义信息

判断类是否存在,ClassUtils.isPresent()

判断Bean是否存在,ListableBeanFactory列出Bean信息

判断存在某些bean,不存在bean进行自动配置

如何查看是否使用了自动配置

--debug打印包含,不包含的一些自动配置

Positive matches:

Negative matches:

Exclusion matches:

uncondition matches:

起步依赖

解决问题:

对于一个服务的依赖,例如mybatis,不知道具体有多少具体依赖包的问题

面向功能,根据功能解析对应需要的依赖

自动配置 + 依赖管理

配置的优先级

DevTools

@TestPropertySource注解

Java命令参数

System.getProperties()

操作系统环境变量

Actuator监控

监控并管理应用程序

两种方法:http,jmx

功能

显示bean,缓存,配置项,环境信息,日志级别,heapdump

image-20220516165757259

Spring-boot-admin监控

提供可视化管理界面,提供通知机制

启动原理

www.cnblogs.com/theRhyme/p/…

1.启动类上添加注解,执行启动类

@SpringBootApplication包含几个子注解**@SpringBootConfiguration@EnableAutoConfiguration**@ComponentScan

@EnableAutoConfiguration开启自动配置:原理是ImportSelector接口+@Conditional注解实现,导入并使用指定配置

2.调用SpringApplication的run方法

SpringApplication.run(SpringDemosApplication.class, args);这个方法创建SpringApplication对象

使用SpringFactoriesLoader加载工厂类

原理:读取META-INF/spring.factories 找到并加载了很多工厂类,例如listener,通过反射实例化为各个配置类

3.初始化一堆Listener,这里是观察者模式

具体执行了这些操作:

  1. 创建一个StopWatch实例,用来记录SpringBoot的启动时间
  2. 通过SpringFactoriesLoader加载listeners:比如EventPublishingRunListener
  3. 发布SprintBoot开始启动事件(EventPublishingRunListener#starting()
  4. 创建和配置environment(environmentPrepared()
  5. 打印SpringBoot的banner和版本
  6. 创建对应的ApplicationContext:Web类型,Reactive类型,普通的类型(非Web)
  7. prepareContext
    1. 准备ApplicationContext,Initializers设置到ApplicationContext(contextPrepared())
    2. 打印启动日志,打印profile信息(如dev, test, prod)
    3. 最终会调用到AbstractApplicationContext#refresh方法,实际上就是Spring IOC容器的创建过程,并且会进行自动装配的操作,以及发布ApplicationContext已经refresh事件,标志着ApplicationContext初始化完成(contextLoaded())
  8. afterRefresh hook方法
  9. stopWatch停止计时,日志打印总共启动的时间
  10. 发布SpringBoot程序已启动事件(started())
  11. 调用ApplicationRunner和CommandLineRunner
  12. 最后发布就绪事件ApplicationReadyEvent,标志着SpringBoot可以处理就收的请求了(running())

SpringIOC 容器初始化过程

由于现在大都是用SpringBoot开发,所以呢,Spring IOC 初始化的源码,就是AnnotationConfigApplicationContext中的源码,IOC的初始化就是该类实例创建的过程。

创建的过程(AnnotationConfigApplicationContext的构造方法

  1. 给我们的Bean,创建与之对应的BeanDefinition,然后把他们放入ConcurrentHashMap(key:beanName和value:beanDefinition)中;BeanDefinition实际上包括一些Bean的信息,比如BeanName, Scope, 是否被**@Primary注解修饰,是否是@Lazy**,以及**@Description**等注解
  2. 入口是**refresh()**方法: 创建IOC需要的资源
  • 初始化BeanFactory, set一些属性,如BeanClassLoadersystemEnvironment
  • 如果是SpringBoot程序,会调用方法进行自动装配:AutoConfigurationImportSelector.AutoConfigurationGroup#process,见:@EnableAutoConfiguration的总结
  • 注册MessageSource,国际化相关的资源,到ApplicationContext
  • 注册ApplicationListener到ApplicationContext
  • 实例化化lazy-init的Bean
  • 最后,publish相关的事件,ApplicationContext 就初始化完成,整个IOC容器初始化完成(IOC容器的本质就是初始化BeanFactory和ApplicationContext),就可以从IOC容器中获取Bean自动注入了

Bean的初始化

PostPostProcessor前置 - 检查是否是InitializingBean - init方法 - PostProcessor后置

初始化顺序

Constructor > @PostConstruct > InitializingBean > init-method

初始化区别

spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定

实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点;

init-method方式消除了对spring的依赖;

BeanFactory和ApplicationContext的区别

他俩都是接口,Application继承了Beanfactory

Beanfactory提供了实例化对象和获取对象的功能

Application提供了国际化,资源加载等功能,在启动之初创建所有bean

MVC处理请求的流程

image-20220517134142080

1.用户发送请求,DispatcherServlet收到请求

2.DispatcherServlet调用HandlerMapping处理器映射器,查询对应的handler,返回执行链

3.Handler根据请求url匹配找到具体的Controller,生成处理对象的Controller以及Filter,返回给DispatcherServlet

4.DispatcherServlet通过handlerAdapter适配器找到并调用Controller中具体的的方法

5.执行处理器具体方法,Controller调用service,dao等执行具体方法

6.Controller处理完成,返回Model和view给HandlerAdapter

7.Handler将model and view 返回给dispatcherServlet

8.Dispatcher将mode and view交给viewResolver视图解析

9.viewResolver解析后返回具体view

10.DispatcherServlet对view进行渲染视图,

11.DispatcherServlet响应请求,返回结果

名词解析

  • DispatcherServlet:前端控制器,也称为中央控制器,它是整个请求响应的控制中心,组件的调用由它统一调度。
  • HandlerMapping:处理器映射器,它根据用户访问的 URL 映射到对应的后端处理器 Handler。也就是说它知道处理用户请求的后端处理器,但是它并不执行后端处理器,而是将处理器告诉给中央处理器。
  • HandlerAdapter:处理器适配器,它调用后端处理器中的方法,返回逻辑视图 ModelAndView 对象。
  • ViewResolver:视图解析器,将 ModelAndView 逻辑视图解析为具体的视图(如 JSP)。
  • Handler:后端处理器,对用户具体请求进行处理,也就是我们编写的 Controller 类。

BEANFACTORY和FACTORYBEAN的区别与联系

  1. 两者都是接口;

  2. BeanFactory主要是用来创建Bean和获得Bean的;

  3. FactoryBean跟普通Bean不同,其返回的对象不是指定类的一个实例,而是该FactoryBean的getObject方法所返回的对象;

    自己是个bean对象,并提供getObject方法生产bean对象,getobject,getType,isSingleton

  4. 通过BeanFactory和beanName获取bean时,如果beanName不加&则获取到对应bean的实例;如果beanName加上&,则获取到FactoryBean本身的实例

  5. FactoryBean 通常是用来创建比较复杂的bean(如创建mybatis的SqlSessionFactory很复杂),一般的bean 直接用xml配置即可,但如果创建一个bean的创建过程中涉及到很多其他的bean 和复杂的逻辑,用xml配置比较困难,这时可以考虑用FactoryBean。

  6. SqlSessionFactory包含mybatis-config,Mapper等

什么是协程

www.cnblogs.com/theRhyme/p/…