敖丙思维导图-Spring

敖丙思维导图系列目录

这些知识整理都是自己查阅帅丙资料(当然还有其他渠道)加以总结滴~ 每周都会更新知识进去。
如有不全或错误还请大家在评论中指出~


  1. 敖丙思维导图-集合
  2. 敖丙思维导图-多线程之synchronizedThreadLocalLockVolatitle线程池
  3. 敖丙思维导图-JVM知识整理
  4. 敖丙思维导图-Spring
  5. 敖丙思维导图-Redis
  6. 敖丙思维导图-RocketMQ+Zookeeper
  7. 敖丙思维导图-Mysql数据库
  • 敖丙思维导图系列目录
    • Spring
    • 设计模式
    • Spring Bean的生命周期(createBean中的doCreateBean)
      • 概述 (实例化+属性赋值+初始化+销毁)
      • 详细步骤
      • 循环依赖情况(- 不支持prototype 应为bean实例不唯一)
      • 解决循环依赖(A-B-A)
      • Spring Bean的作用域
    • 父子容器
    • Spring事务
      • 事务的隔离级别
      • 事务的7种传播机制
      • @Transactional失效场景
    • IOC容器(避免在各处new来创建类,做到统一维护)
      • 自己设计IOC容器
    • Bean
    • AOP
      • 为什么JDK动态代理要实现接口
        • 静态代理
    • BeanFactory 、FactoryBean、ObjectFactory
      • BeanFactory和ApplicationContext的区别
    • SpringBoot – 开箱即用 约定大于配置
      • SpringApplication的初始化:
      • run()方法
      • 常用注解
    • Spring的启动流程

  • (SentinelBeanPostProcessor)
  1. postProcessBeforeInstantiation在doCreateBean之前调用,也就是在bean实 化之前调用的,该方法的返回值会替换原本的Bean作为代理,这也是。
  2. postProcessAfterInstantiation在真正执行赋值操作之前,返回false时可以阻断属性赋值阶段。

执行顺序
BeanPostProcessor有很多个,而且每个BeanPostProcessor都影响多个Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。
1 PriorityOrdered是一等公民,首先被执行,PriorityOrdered公民之间通过接口返回值排序
2 Ordered是二等公民,然后执行,Ordered公民之间通过接口返回值排序
3 都没有实现是三等公民,最后执行

第二大类:只调用一次的接口

  • Aware类型的接口
  • 生命周期接口
  1. Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。Aware都是在初始化阶段之前调用

Aware Group1
1 BeanNameAware
2 BeanClassLoaderAware
3 BeanFactoryAware
Aware Group2
1 EnvironmentAware
2 EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。
3 ApplicationContextAware

  1. 两个生命周期接口
  • InitializingBean 对应生命周期的初始化阶段。(在初始化方法中放心大胆的使用Aware接口获取的资源,这也是我们自定义扩展Spring的常用方式)
  • DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法 。

循环依赖情况(- 不支持prototype 应为bean实例不唯一)

  • 构造器循环依赖(singleton prototype-通过@Scope()指定 ) 都不支持 (因为你一上来就要属性注入)
  • Setter注入循环依赖(singleton prototype) – 只支持singleton Setter注入

scope=singleton(默认,单例,生成一个实例) 不是线程安全,性能高
scope=prototype(原型多线程, 生成多个实例)

解决循环依赖(A-B-A)

  1. 初次创建A(getBean())时,调用addsingletonFactory将A实例对应的ObjectFactoy放到三级缓存中,调用populateBean赋值属性B;()
  2. 因为A依赖B,调用getBean获取B。将B的ObjectFactoy放到三级缓存,调用populateBean赋值B,此时因为B依赖A,此时进入方法, (单例工厂实例),就调用单例工厂的getObject方法;将实例A;从A。
  3. getBean(A),将A对应的实例赋值到B
  4. 彻底完成B的创建,返回给A
  5. A放入一级缓存,并清空其它级缓存

Spring Bean的作用域

作用域 描述
singleton 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。
session 同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。
application 限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。

  • 开箱即用
    SpringBoot所有自动配置类都是在启动的时候进行扫描并加载,通过可以找到自动配置类的路径,但是不是所有存在于spring,factories中的配置都进行加载,而是通过注解进行判断条件是否成立(只要导入相应的,条件就能成立),如果条件成立则加载配置类,否则不加载该配置类。
  • 约定大于配置
    我们的配置文件(.yml)应该放在哪个目录下,配置文件的命名规范,项目启动时扫描的Bean,组件的默认配置是什么样的(比如SpringMVC的视图解析器)等等等等这一系列的东西,都可以被称为约定,

SpringApplication的初始化:

  1. 推断web应用类型 ( 响应式非阻塞)
  2. 初始化应用上下文
    从Map中根据org.springframework.context.ApplicationContextInitializer的类型拿到需要的类初始化类,进入getOrDefault把加载到的
  3. 初始化监听器类
    初始化监听类的时候和上面初始化应用上下文是一样的代码。
    唯一不同的是getSpringFactoriesInstances(ApplicationListener.class))传进去的是,而初始化应用上下文传入的参数是。
  4. 推演出主程序类

应用上下文即是Spring容器抽象的一种实现;而我们常见的ApplicationContext本质上说就是一个维护Bean定义以及对象之间协作关系的高级接口。Spring的核心是容器,而容器并不唯一,框架本身就提供了很多个容器的实现,大概分为两种类型:一种是不常用的BeanFactory,这是最简单的容器,只能提供基本的DI功能;还有一种就是继承了BeanFactory后派生而来的应用上下文,其抽象接口也就是我们上面提到的的ApplicationContext,它能提供更多企业级的服务,例如解析配置文本信息等等,这也是应用上下文实例对象最常见的应用场景。有了上下文对象,我们就能向容器注册需要Spring管理的对象了。对于上下文抽象接口,Spring也为我们提供了多种类型的容器实现,供我们在不同的应用场景选择。

run()方法

  1. 加载运行监听器(各种listener)
  2. 根据Web应用类型来创建对应的环境
  3. 根据Web应用类型来创建容器
  4. 准备应用上下文 prepareContext
  5. 刷新应用上下文 (这时创建了Tomcat对象)
  6. 发布监听应用启动事件
  7. 执行Runner
  8. 发布上下文准备完成的事件

在SpringBoot中启动tomcat的工作在刷新应用上下文上下这一步。而tomcat的启动主要是实例化两个组件:Connector、Container,一个tomcat实例就是一个Server,一个Server包含多个Service,也就是多个应用程序,每个Service包含多个Connector和一个Container,而一个Container下又包含多个子容器。

常用注解

(开启自动配置)
包含@SpringBootConfiguration 、@EnableAutoConfiguration、@ComponentScan通常用在主类上;

@ComponentScan:其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。
@EnableAutoConfiguration:从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
@SpringBootConfiguration:继承自@Configuration,二者功能也一致,标注当前类是配置类,
并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。

用于标注数据访问组件,即DAO组件;

用于标注控制层组件(如struts中的action),包含@Controller和@ResponseBody;
@Component:
泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注;
@RequestBody:
参数前加上这个注解之后,认为该参数必填。表示接受json字符串转为对象 List等;
@AutoWired:
byType方式。把配置好的Bean拿来用,完成属性、方法的组装,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作;
当加上(required=false)时,就算找不到bean也不 错;

@Qualifier:
当有多个同一类型的Bean时,可以用@Qualifier(“name”)来指定。与@Autowired配合使用;

@RequestMapping:
RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径;

该注解有六个属性:
params:指定request中必须包含某些参数值是,才让该方法处理。
headers:指定request中必须包含某些指定的header值,才能让该方法处理请求。
value:指定请求的实际地址,指定的地址可以是URI Template 模式
method:指定请求的method类型, GET、POST、PUT、DELETE等
consumes:指定处理请求的提交内容类型(Content-Type),如application/json,text/html;
produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。

@ControllerAdvice:
包含@Component。可以被扫描到。统一处理异常;

@ExceptionHandler(Exception.class):
用在方法上面表示遇到这个异常就执行以下方法。

Spring的启动流程

  1. web应用部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;
  2. web容器启动时,会触发容器初始化事件。创建ContextLoaderListener,回调contextInitialized方法
  3. 创建并初始化spring容器。
  4. 创建WebApplicationContext对象(解析web.xml或者原生Servlet3.0的注解)。
  5. refresh容器,读取XML配置,创建beans。
  6. spring容器引用保存到ServletContext和ContextLoaderListener中。

这样每个servlet 就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览93917 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年5月16日
下一篇 2020年5月16日

相关推荐