Spring
什么是Spring
Spring是开源的容器框架。其核心思想是IoC和AOP。
IoC
控制反转。实例不再由调用者创建,而是由Spring容器创建和管理。实例控制权的转变就是控制反转。其一可以减少耦合性,其二达到资源的复用。依赖注入(DI)是对IoC的一种具体实现。
AOP
面向切面编程。编译期和运行期间,在不修改源码的情况下,实现程序功能的统一维护。常用在权限拦截、事务处理、参数验证、性能监控、日志等方面。
Spring IoC中三种依赖注入方式
1.set方法注入
2.构造方法注入
3.Autowired注解自动装配
BeanFactory和ApplicationContext
BeanFactory是IoC容器的根接口。提供获取bean、是否包含bean等方法。
ApplicationContext扩展了BeanFactory的特性,新增支持国际化、统一加载资源、事件传播等特性。被称为Spring上下文。
BeanFactory按需加载bean,而ApplicationContext在启动时加载所有bean。
什么是bean?
bean是指那些被IoC容器所管理的对象。
什么是bean装配?
装配是指在Spring容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。
Spring框架中的bean是线程安全的吗?
线程不安全,Spring生成的bean默认都是单例。在使用过程中,应避免在Controller中定义实例变量。如果要定义实例变量,可用ThreadLocal来维护变量;或者通过scope属性把bean设置成非单例。
Spring单例bean带来的好处
1.只在初始化时实例化一次,提高了效率。
2.减少了内存开销,减少了对象创建和垃圾收集的时间。
Spring中bean的作用域
1.singleton:单例。默认值。整个IoC容器中只创建一个bean实例。
2.prototype:原型。每次从容器中获取bean时,都返回一个新的实例。
3.request:请求。每次HTTP请求都会创建一个新的bean,该bean仅在当前请求中有效。
4.session:会话。同一个HTTP Session共享一个bean。
5.globalsession:全局会话。一般用于Portlet应用环境,该作用域仅适用于WebApplicationContent环境。
Java在创建对象时,需要进行内存申请;销毁实例时,需要完成垃圾回收,这些工作都会增加系统开销。因此,Bean的作用域越大,销毁代价比较大。
Spring中bean的生命周期
实例化bean、设置对象属性、bean前置处理、初始化bean、bean后置处理、使用bean、销毁bean
AOP的基本概念:
1.切面(Aspect):其实就是共有功能的实现。如日志切面、权限切面、事务切面等。在实际应用中通常是一个存放共有功能实现的普通Java类,之所以能被AOP容器识别成切面,是在配置中指定的。
2.通知(Advice):是切面的具体实现。以目标方法为参照点,根据放置的地方不同,可分为前置通知(Before)、后置通知(AfterReturning)、异常通知(AfterThrowing)、最终通知(After)与环绕通知(Around)5种。在实际应用中通常是切面类中的一个方法,具体属于哪类通知,同样是在配置中指定的。
3.连接点(Joinpoint):就是程序在运行过程中能够插入切面的地点。例如,方法调用、异常抛出或字段修改等,但spring只支持方法级的连接点。
4.切入点(Pointcut):用于定义通知应该切入到哪些连接点上。不同的通知通常需要切入到不同的连接点上,这种精准的匹配是由切入点的正则表达式来定义的。
5.目标对象(Target):就是那些即将切入切面的对象,也就是那些被通知的对象。这些对象中已经只剩下干干净净的核心业务逻辑代码了,所有的共有功能代码等待AOP容器的切入。
6.代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。可以简单地理解为,代理对象的功能等于目标对象的核心业务逻辑功能加上共有功能。代理对象对于使用者而言是透明的,是程序运行过程中的产物。
7.织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。这个过程可以发生在编译期、类装载期及运行期,当然不同的发生点有着不同的前提条件。譬如发生在编译期的话,就要求有一个支持这种AOP实现的特殊编译器;发生在类装载期,就要求有一个支持AOP实现的特殊类装载器;只有发生在运行期,则可直接通过Java语言的反射机制与动态代理机制来动态实现。
CGLib动态代理
和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理。
为什么使用Spring?
解耦、简化开发、AOP的支持、方便程序测试、方便和其它框架进行整合
Spring有几种配置方式?
1.基于XML的配置
2.基于注解的配置
3.基于Java的配置
Spring框架中都用到了哪些设计模式?
1.代理模式 AOP功能的实现。
2.工厂模式 通过BeanFactory和ApplicationContext创建bean对象。
3.单例模式 bean默认为单例模式。
4.模板方法模式 以Template结尾的类,比如RestTemplate,JmsTemplate,JpaTemplate。
5.观察者模式 Spring事件驱动模型就是观察者模式很经典的一个应用。当对象间存在一对多关系时,一个对象被修改,则会自动通知依赖它的对象。
6.责任链模式 DispatcherServlet中获取与请求匹配的处理器HandlerExecutionChain,this.getHandler()方法的处理使用到了责任链模式。
7.适配器模式 AOP的增强或通知(Advice)使用到了适配器模式,SpringMVC中也是用到了适配器模式适配Controller。
Spring事务管理的方式有几种?
编程式事务和声明式事务。编程式事务是通过在代码中显式地编写事务来实现事务管理,Spring提供了TransactionTemplate和TransactionManager两个核心类来支持编程式事务管理。声明式事务由AOP实现。
Spring声明式事务的5种配置方式
1.每个Bean都有一个代理。
2.所有Bean共享一个代理基类。
3.使用拦截器。
4.使用tx标签配置的拦截器。
5.全注解,添加Transactional注解。
Spring五个事务隔离级别和七个事务传播行为
隔离级别是指若干个并发的事务之间的隔离程度。TransactionDefinition接口中定义了五个表示隔离级别的常量:
ISOLATION_DEFAULT这是一个PlatfromTransactionManger默认的隔离级别,使用数据库默认的事务隔离级别,另外四个与JDBC的隔离级别相对应。
ISOLATION_READ_UNCOMMITTED这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED保证一个事务修改的数据提交后才能被另一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离可以避免脏读的出现,但是可能出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ这种事务隔离可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION_SERIALIZABLE这是花费最高代价最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
所谓事务的传播行为是指,如果在开始当前事务之前,一个事务上下文已经存在,此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:
PROPAGATION_REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
PROPAGATION_SUPPORTS:如果存在一个事务,支持当前事务。如果没事务,就以非事务方式执行。
PROPAGATION_MANDATORY:如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。
PROPAGATION_REQUIRES_NEW:总是开启一个新的事务。如果一个事务已经存在,则将这个事务挂起。
PROPAGATION_NOT_SUPPORTED:总是非事务地执行,并挂起任何存在的事务。
PROPAGATION_NEVER:总是非事务的执行,如果存在一个活动事务,则抛出异常。
PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按PROPAGATION_REQUIRED属性执行。
SpringMVC
SpringMVC是Spring提供的一个web框架。主要由DispatcherServlet、处理器映射、控制器、视图解析器、视图组成。
SpringMVC流程
1.用户发送请求至前端控制器DispatcherServlet。
2.DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3.处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4.DispatcherServlet调用HandlerAdapter处理器适配器。
5.HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6.Controller执行完成返回ModelAndView。
7.HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
8.DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
9.ViewReslover解析后返回具体View。
10.DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11.DispatcherServlet响应用户。
SpringCloud
一个服务治理平台,提供了全套的分布式系统解决方案。
SpringCloud常用组件
1.Eureka
服务注册和发现功能
2.Ribbon
基于HTTP和TCP的客服端负载均衡工具。提供多种负载均衡算法,如轮询、随机、指定权重等,默认使用轮询。
3.Feign
声明式、模板化的HTTP客户端,集成了Ribbon和RestTemplate,像调用本地方法一样调用远程服务。Feign默认使用JDK原生的URLConnection发送HTTP请求,生产环境可使用ApacheHttpClient或OkHttp。
4.Hystrix
断路器。用来预防服务雪崩的现象,给不可用、超时的服务做降级处理。
5.Gateway
网关服务,提供对外API接口,权限验证,路由,限流,监控。
6.Config
分布式配置中心。方便配置文件统一管理,实时更新。支持服务配置和Git。
Hystrix熔断触发条件
默认情况Hystrix如果检测到10秒内请求的失败率超过50%,就触发熔断机制。之后每隔5秒重新尝试请求微服务,如果服务不能响应,继续走熔断机制。如果服务可用,则关闭熔断机制,恢复正常请求。
什么是服务熔断?什么是服务降级?
熔断是下游服务不可用或超时时,断开与下游服务的交互,防止服务雪崩。当监测到下游服务正常时,恢复下游服务的调用。
降级是流量大时,优先保证核心服务,对于非核心服务可以选择将其关闭。
Spring版本变迁
Spring1 2003年发布,包含了核心的IoC和AOP功能。完全是xml的配置。
Spring2 支持基于注解的配置、SpringMVC、JDBC模板等。
Spring3 开始在GitHub上托管代码。不再提供一个大的完整的jar包,而是拆成20个小的jar包。
Spring4 SpringBoot诞生,支持Java8。
Spring5 2017年发布,支持Java9。
Spring6 2022年发布,支持Java17。