Spring

2021-11-02  本文已影响0人  小丸子的呆地

什么是spring

spring是一个轻量级的容器框架,目的是简化企业应用开发,核心有两大功能IOC和AOP,通过IOC可以帮助我们管理项目中对象依赖,通过AOP可以帮助我们动态增强应用的功能性。spring对现有主流框架都有集成的支持,让我们我们很容易的在应用中使用其他框架的功能。

什么是IOC

控制反转,IOC其实就是对象的生命周期交给spring管理,spring本身是一个bean容器,帮助我们创建并且缓存对象引用,当我们需要某个对象的时候,由spring进行创建;过程中需要DI依赖注入,将我们需要的对象引用赋值给变量,降低组件之间耦合性;对象与对象之间复杂的引用关系也由spring帮我们管理;第三方功能需要的对象也由spring帮我们管理,我们只需要拿来即用就好。

什么是AOP

面向切面,切面指不同功能不同业务中相同的一部分逻辑,比如鉴权、日志、事务等模块,aop可以帮助我们轻易的在每个业务中进行这些通用功能的拓展,让我们只专注于实现业务功能即可。
当你需要在很多方法或接口上增加相同或相似的逻辑时,可以考虑使用AOP。
AOP有两种实现方式Spring的实现和AspectJ的实现,AspectJ是早期的aop实现,定义了一些标准的枚举,这些枚举spring也在使用,AspectJ的实现方式是使用静态代理增强,在代码编译期间将切面逻辑织入对象;spring是通过动态代理,JDK或者CGlib,在对象创建期间。

AOP中的概念

连接点(Join point) 被切入的执行中的方法
切点(pointcut) 定义的一组被切入的方法
通知(advice) 在连接点上执行的方法包括Around、Before、After、After returning、After throwing
切面(aspect) 被提取的公共模块 切面就是一个pointcut + 一组advice
目标对象(target) 包含连接点的对象
织入(Weaving) 通过代理等方法,在target的join point中执行advice

AOP实现的方式

spring实现的AOP,动态代理,jdk面向接口、cglib子类继承,对象创建期间、getBean

AspectJ实现的AOP,静态代理增强,代码编译期间将切面逻辑织入对象

什么是spingmvc

springmvc是spring提供的web应用框架,采用mvc模式modile-view-controller,springmvc本身是spring拓展出来的一个模块,spring对他提供很好的继承支持,通过@Controller和@RequestMapping我们可以很简单的创建一个web接口,核心dispatcherservlet拦截所有请求,根据uri找到对应的handler方法并执行,返回对应视图数据。

springmvc组件

springmvc运行原理

springmvc启动的时候会创建自己的上下文applicationcontext对象,将所有controller信息载入上下文,一个reqeustmapping就是一个contoller

  1. 客户端请求提交到DispatcherServlet
  2. 由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller
  3. DispatcherServlet将请求提交到Controller
  4. Controller调用业务逻辑处理后,返回ModelAndView
  5. DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图
  6. 视图负责将结果显示到客户端

springmvc中拦截器和过滤器的区别

过滤器是Servlet定义的规范、由servlet容器进行实现,拦截器是由springmvc定义并且实现的
过滤器在servlet之前调用,拦截器存储在HandlerExecutionChain中,在DispatcherServlet中调用
过滤器拦截所有请求,拦截器只能拦截定义的handler
过滤器是责任链模式,拦截器是代理模式(静态代理的)

什么是springboot

本质上springboot还是spring,在spirng的基础上做了一些更方便我们搭建项目的功能,让我们在编码、配置、部署、监控等方面变的更简单了。
基于约定大于配置的自动装配,我们减少了很多配置项,starter帮助我们更简单的管理依赖,内置servlet容器,让我们更快的启动部署一个应用。

什么是springcloud

springcloud是spring提出的一套关于微服务架构的组件,包含网关、注册中心、配置中心、RPC、熔断降级、负载均衡、mq、分布式事务等组件

spring启动过程

spring的启动过程在AbstractApplicationContext.refresh()方法中执行

  1. prepareRefresh(); 准备上下文刷新 准备一些集合容器
  2. *创建Bean工厂ConfigurableListableBeanFactory
  3. 在使用之前准备一下BeanFactory内部的一些信息 环境参数等
  4. *postProcessBeanFactory 允许子类对BeanFactory做一些后置处理,模板方法
  5. *invokeBeanFactoryPostProcessors 执行Bean工厂后置处理器 会加载BeanDefinition
  6. *registerBeanPostProcessors 注册Bean后置处理器
  7. initMessageSource 初始化消息源
  8. initApplicationEventMulticaster 初始化应用事件广播器
  9. *onRefresh 正在refresh,模板方法,交由子类实现,ServletWebServerApplicationContext会在此处创建web服务器
  10. registerListeners 注册观察者们
  11. *finishBeanFactoryInitialization 根据BeanDefinition实例化所有Bean对象
  12. *finishRefresh 完成刷新 推送event消息,ServletWebServerApplicationContext重写此方法,增加了启动web服务器的逻辑

beandefinition作用

beandefinition是Bean定义信息,spring依靠beandefinition进行实例化,在spring容器启动执行invokeBeanFactoryPostProcessors方法时会扫描路径上的所有Bean对象,加载他们的BeanDefinition信息到BeanFactory中,后面会根据这些信息进行Bean的实例化

springboot启动过程

spring中bean加载过程

实例化Bean 通过反射调用class的构造方法或者通过@Bean设置的实例化方法 此时Bean对象所有属性都是默认值
为Bean对象进行属性填充 这个阶段会遇到循环依赖问题 注入自定义对象
为Bean对象填充awera信息 注入上下文对象
执行BeanPostProcessor前置方法
执行init方法
执行BeanPostProcessor后置方法
将Bean放入BeanFactory

所有BeanPostProcessor都会在aware之后执行么

有一些BeanPostProcessor会提前到populateBean阶段执行
AOP、Autowaire、dubbo的Refrence
InstantiationAwareBeanPostProcessor
DestructionAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor

spring解决循环依赖

spring循环依赖问题:spring中交由BeanFactory创建Bean对象,而创建Bean对象过程中有可能依赖了其他对象也需要创建,如果两个对象互相依赖那么创建过程就会进入一个死循环;单缓存无法解决,是因为对象没有创建完毕就放入缓存是不安全的;双缓存可以解决,但是对于aop无法处理,spring实现aop是在BeanPostProcessor阶段,如果强行处理就需要把aop提前到Bean实例化阶段,侵入了标准Bean的创建;三级缓存解决aop动态代理问题
解决方法:
A对象实例化之后创建一个ObjectFactory放入三级缓存,ObjectFactory是一段lambda表达式,执行了获取A对象最终引用的代码,过程中执行一些BeanPostProcessor处理包括AOP;
A对象属性填充阶段加载B对象,实例化B对象之后也放入三级缓存,进入B的属性填充,B的属性填充阶段需要加载A对象,从三级缓存取出对象引用放入二级缓存,并执行属性填充;
B属性填充等一些列代码执行完毕后,将B对象的从三级缓存取出放入一级缓存;
A对象拿到B的引用,进行属性填充完毕,从二级缓存出去放入一级缓存

springmvc父子容器

springmvc启动的时候,加载DispatcherServlet的时候会再创建一个ApplictionContext,并将Spring已经创建的向下文设置为父级,形成父子容器
父子容器的存在主要是为了划分边界,service层我们使用spring框架,对象功能由spring帮我们管理,而在web层可能存在多实现,比如springmvc struts2,父子容器可以帮助我们很容易的替换web层,只需要将spring-servlet.xml替换成Struts的配置文件struts.xml,service层都不用动。
控制扫描路径,来规避父子容器扫描的Bean对象
SpringBoot中使用的是同一个容器,将DispatcherServlet作为一个Bean对象交由Spring启动了,以前是交由tomcat启动。

springmvc常用注解

@Controller 标记是一个contoller
@RequestMapping 标记资源路径
@RequestParam 标记参数名称,必填
@RequestAttribute 标记属性名称,必填
@RequestBody 标记参数是Json体
@ResponseBody 标记返回时Json体
@RestController 标记controller内部全是json方法
@WebFilter 过滤器
@CrossOrigin 标记请求与

spring加载bean的几种方式

@Component
@Configuration
<bean/>
@Bean
<import/>
@Import
ImportSelector接口
ImportBeanDefinitionRegistrar接口

springboot自动装配原理

springboot自动为我们创建一些Bean对象,基于约定大于配置的原则,按照默认值去创建。
@SpringBootApplication修饰了启动类,@SpringBootApplication包含@EnableAutoConfiguration
@EnableAutoConfiguration包含@Import(AutoConfigurationImportSelector.class)
所有需要自动装配的类是依靠AutoConfigurationImportSelector,从spring.factories文件中加载所有配置为EnableAutoConfiguration的类
装配时机是在启动时,context.refresh()中,执行BeanFacotoryPostProcessor阶段,通过ConfigurationClassPostProcessor加载

springboot内嵌tomcat原理

  1. SpringApplication在实例化阶段会根据路径上引用的一些class推测当前应用的类型,如果存在Servlet或者ConfigurableWebApplicationContext会被推测为是一个web服务器;
  2. SpringApplication.run阶段创建上下文时,会根据上面推测的应用类型创建具体的上下文,这里会创建AnnotationConfigServletWebServerApplicationContext
  3. 这个context在refresh阶段的onRefresh中会创建webServer,默认是tomcat,加载的ServletWebServerFactory默认是tomcat的,根据是否引用了内置tomcat其他的还有jetty、Undertow
    TomcatServletWebServerFactory是通过ServletWebServerFactoryAutoConfiguration自动装配的,条件是路径上有Tomcat、Servlet
  4. 在refresh阶段的finishRefresh中会启动webServer

spring和springboot中提供了哪些扩展点

BeanFactoryPostProcessor Bean工厂后置处理器 可以通过ApplicationContextInitializer加载,或者只要在refresh方法之前通过listener加载
BeanPostProcessor Bean后置处理器
ApplicationRunListener 广播springboot启动事件
ApplicationListener 广播spring启动事件

ApplicationContextInitializer在什么时机执行

SpringApplication.run.prepareContext;

springboot的starter原理

管理依赖,省去了以前引入一大堆依赖,还要梳理版本,弄不好就会冲突,
自动装配组件,省去了一大堆配置
统一配置文件,将所有配置统一到spring的配置文件中,便于管理

手写starter

一般分为两个包 一个starter包负责引入依赖,一个autoconfiguration包负责自动装配组件
starter包不需要任何代码,只引入依赖
autoconfiguration包定义配置类,定义组件Bean,自动装配
配置文件类:使用@ConfigurationProperties(prefix = "demo")修饰的Java类,属性名就是配置名
自动配置类:@EnableConfigurationProperties(DemoProperties.class)修饰的Java类,会自动读取spring配置文件中对应配置信息
定义组件:完成核心业务,并用@Bean等方式定义为一个Bean对象
自动装配:在META-INF目录下添加spring.factories,并配置org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx.DemoAutoConfiguration

BeanFactory和ApplicationContext

BeanFactory是bean工厂,ApplicationContext是应用上下文
ApplicationContext实现了BeanFactory通过门面模式支持了BeanFactory中的方法,内部引用了一个DefaultListabledBeanFactory
ApplicationContext还负责整个应用的生命周期,BeanFactory只管Bean对象

BeanFactory和FactoryBean

BeanFactory是bean工厂,简单工厂模式;
FactoryBean是一个Bean,工厂方法模式,getBean方法中对其特殊处理,如果是FactoryBean实现类并且非急切加载的话,会后置处理,当获取FactoryBean时会自动调用getOBject方法,如果需要FactoryBean对象,需要getBean("&"+name),用于懒加载对象,或加载复杂对象实现,比如

spring中的设计模式

Listener 观察者模式
HandlerAdapter 适配器模式
AOP 代理模式
ApplicationContext 门面模式
AbstractApplicationContext.refresh() 模板方法
BeanFactory 简单工厂
FactoryBean和ObjectBean 工厂方法
Waraper 装饰模式

springcloud有哪些组件

网关 配置中心 注册中心 服务调用RPC 负载均衡 熔断降级 限流 路由 分布式消息 分布式事务

spring中的事务

基于AOP + Threadlocal实现

spring中的事务传播

required 如果存在就加入,如果没有就创建
supports 如果存在就加入,如果没有就非事务执行
not_supports 如果存在就挂起,非事务执行
required_new 如果存在就挂起,开启一个新事物执行
mandatory 如果不存在事务,抛异常
never 如果存在事务,抛异常
nested 嵌套事物,子事务不影响父,父回滚,子回滚

spring中事务失效的场景

私有方法、final方法、多线程调用、非spring管理对象、直接调用、吞异常、数据库不支持事务、

@Resouce和@Autowire的区别

resouce getBeanByName J2ee注解
autowire getBeanByType spring注解 配合@Qualifier根据name加载;可以装配多个实例到集合或者map

上一篇下一篇

猜你喜欢

热点阅读