Skip to content

Spring

Spring是一个IOC框架,它最核心的3个组件:SpringCore、SpringContext和SpringBean,他们为Spring打下了基础,支持了Spring的框架结构。Spring的其他功能特性,如Web、AOP、JDBC等都是基于它而开发的。

IOC

Inverse of Control: 把本来在类内部控制的对象,反转到类外部,由第三方系统去控制这个内置对象的创建并注入,不再由自己本身控制这个内置对象的创建

  • 实现:
    • 容器控制了对象的外部资源和生命周期,由容器帮我们查找并注入依赖的对象,对象只能被动的接收依赖对象,依赖对象的获取被反转了,IoC 容器实际上就是个 Map
    • 依赖注入
      • 构造器注入
      • Setter方法注入
      • 接口注入

AOP

Aspect Oriented Programming: 面向切面编程

  • 组件
    • Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice
    • Joint point(连接点):表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
    • Pointcut(切点):表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
    • Advice(增强):Advice 定义了在 Pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
    • Target(目标对象):织入 Advice 的目标对象
    • Weaving(织入):将 Aspect 和其他对象连接起来, 并创建 Adviced object 的过程
  • 实现方式
    • 基于Schema来实现 xml
    • 基于aspectJ实现(配置/注解)
  • 代理方式
    • JdkProxy:假如说这个对象所在的类上面有接口(基于接口来做的),Spring会默认使用JdkProxy(JDK的动态代理),来生成一个代理,在代理里进一步的把所有对这个类做的增强操作,放到代理执行的代码里面。然后先做了增强的操作,再去调用原本的类的他的方法。
    • proxyTargetClass:如果要代理的类有接口但想强制不用默认JDK的动态代理,也是用字节码增强的技术,就可以开启proxyTargetClass选项。同CGlib
    • CGlib:假如说要增强或代理的这个类没有接口,只有一个类的定义,Spring会默认使用CGlib,对他做字节码增强。相当于硬生生的给他生成一个子类。在这个子类里,当我们调用原先这个类的某个方法时,先做增强操作,再去调原本类的方法,最后再把结果返回回来
  • 事务
    • 事务的传播行为
      • PROPAGATION_REQUIRED
      • PROPAGATION_SUPPORTS
      • PROPAGATION_MANDATORY
      • PROPAGATION_REQUIRES_NEW
      • PROPAGATION_NOT_SUPPORTED
      • PROPAGATION_NEVER
      • PROPAGATION_NESTED

Bean的生命周期

流程

  • 首先是实例化Bean,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚末初始化的依赖时,容器就会调用doCreateBean()方法进行实例化,实际上就是通过反射的方式创建出一个bean对象
  • Bean实例创建出来后,接着就是给这个Bean对象进行属性填充,也就是注入这个Bean依赖的其它bean对象
  • 属性填充完成后,进行初始化Bean操作,初始化阶段又可以分为几个步骤
    • 执行Aware接口的方法
    • 执行BeanPostProcessor的前置处理方法postProcessBeforeInitialization(),对Bean进行一些自定义的前置处理
    • 判断Bean是否实现了InitializingBean接口,如果实现了,将会执行InitializingBean的afterPropertiesSet()初始化方法;
    • 执行用户自定义的初始化方法,如init-method等
    • 执行BeanPostProcessor的后置处理方法postProcessAfterInitialization
  • 初始化完成后,Bean就成功创建了,之后就可以使用这个Bean, 当Bean不再需要时,会进行销毁操作
    • 首先判断Bean是否实现了DestructionAwareBeanPostProcessor接口,如果实现了,则会执行DestructionAwareBeanPostProcessor后置处理器的销毁回调方法
    • 其次会判断Bean是否实现了DisposableBean接口,如果实现了将会调用其实现的destroy()方法
    • 最后判断这个Bean是否配置了Destroy-method等自定义的销毁方法,如果有的话,则会自动调用其配置的销毁方法;

拓展点

  • Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
  • Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean这些接口的方法
  • 容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
  • 厂后处理器接口方法:这个包括了AspectJWeavingEnabler,ConfigurationClassPostProcessor,CustomAutowireConfigure等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

设计模式

  • 单例模式
  • 原型模式: 原型模式也叫克隆模式,Spring中该模式使用的很明显,和单例一样在bean标签中设置scope的属性prototype即表示该bean以克隆的方式生成
  • 模板模式: 模板模式的核心是父类定义好流程,然后将流程中需要子类实现的方法就抽象话留给子类实现,Spring中的JdbcTemplate就是这样的实现。我们知道jdbc的步骤是固定
  • 观察者模式: 观察者模式定义的是对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。使用比较场景是在监听器中而spring中Observer模式常用的地方也是listener的实现。如ApplicationListener
  • 工厂模式:
    • 简单工厂模式: 简单工厂模式就是通过工厂根据传递进来的参数决定产生哪个对象。Spring中我们通过getBean方法获取对象的时候根据id或者name获取就是简单工厂模式了。
    • 工厂方法模式: 在Spring中我们一般是将Bean的实例化直接交给容器去管理的,实现了使用和创建的分离,这时容器直接管理对象,还有种情况是,bean的创建过程我们交给一个工厂去实现,而Spring容器管理这个工厂。这个就是我们讲的工厂模式,在Spring中有两种实现一种是静态工厂方法模式,一种是动态工厂方法模式。
  • 适配器模式: 将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。这就是适配器模式。在Spring中在AOP实现中的Advice和interceptor之间的转换就是通过适配器模式实现的。
  • 装饰者模式: 装饰者模式又称为包装模式(Wrapper),作用是用来动态的为一个对象增加新的功能。装饰模式是一种用于代替继承的技术,无须通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。   spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。   具体的使用在Spring session框架中的SessionRepositoryRequestWrapper使用包装模式对原生的request的功能进行增强,可以将session中的数据和分布式数据库进行同步,这样即使当前tomcat崩溃,session中的数据也不会丢失。
  • 代理模式: 代理模式应该是大家非常熟悉的设计模式了,在Spring中AOP的实现中代理模式使用的很彻底.
  • 策略模式: 策略模式对应于解决某一个问题的一个算法族,允许用户从该算法族中任选一个算法解决某一问题,同时可以方便的更换算法或者增加新的算法。并且由客户端决定调用哪个算法,spring中在实例化对象的时候用到Strategy模式。XmlBeanDefinitionReader,PropertiesBeanDefinitionReader
  • 责任链默认: AOP中的拦截器链
  • 委托者模式: DelegatingFilterProxy,整合Shiro,SpringSecurity的时候都有用到。

SpringCloud

组件

注册中心

  • 8大服务治理功能
    • 服务注册
    • 服务续约
    • 服务获取
    • 服务调用
    • 服务下线
    • 失效剔除
    • 自我保护
    • 服务同步
  • 选型
    • zk cp:金融场景,大数据储存场景
    • consul cp
    • eureka ap: 极高可用
      • Eureka Server 也可以运行多个实例来构建集群,解决单点问题,但不同于 ZooKeeper 的选举 leader 的过程,Eureka Server 采用的是Peer to Peer 对等通信。这是一种去中心化的架构,无 master/slave 之分,每一个 Peer 都是对等的。在这种架构风格中,节点通过彼此互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向其他节点。每个节点都可被视为其他节点的副本。
      • 默认情况下,如果 Eureka Server 在一定时间内没有接收到某个服务实例的心跳(默认周期为30秒),Eureka Server 将会注销该实例(默认为90秒, eureka.instance.lease-expiration-duration-in-seconds 进行自定义配置)。当 Eureka Server 节点在短时间内丢失过多的心跳时,那么这个节点就会进入自我保护模式。
    • nacos cp ap: 电商
      • Nacos支持CP+AP模式,即Nacos可以根据配置识别为CP模式或AP模式,默认是AP模式。如果注册Nacos的client节点注册时ephemeral=true,那么Nacos集群对这个client节点的效果就是AP,采用distro协议实现;而注册Nacos的client节点注册时ephemeral=false,那么Nacos集群对这个节点的效果就是CP的,采用raft协议实现。根据client注册时的属性,AP,CP同时混合存在,只是对不同的client节点效果不同。Nacos可以很好的解决不同场景的业务需求。

配置中心

网关

  • SpringCloud Gateway
    • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。 GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定;路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增;当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

负载均衡

  • Ribbon
    • 负载均衡策略
      • 轮询
      • 随机
      • 最小并发
      • 加权轮询
      • 先过滤,再线性轮询
      • 最优最佳
      • 失败重试

声明式远程调用

  • Fegin
    • @FeginClient通过动态代理调用RequsetMapping注解上的URL

核心配件

限流

  • 令牌桶
  • 漏桶
  • 计数器
  • 滑动窗口: 滑动窗口将时间窗口划分为更小的时间片段,每过一个时间片段,时间窗口就会往右滑动一格,每个时间片段都有独立的计数器。我们在计算整个时间窗口内的请求总数时会累加所有的时间片段内的计数器。时间窗口划分的越细,那么滑动窗口的滚动就越平滑,限流的统计就会越精确

断路器

  • 断路器的隔离方式
    • 线程池隔离
    • 信号量隔离: 可以把信号量理解成一个计数器 , 对这个计数器规定一个计数上限, 代表一个接口被访问的最大量.

日志监控

链路追踪

  • skywalking
  • CAT
  • pingpoint
  • zipkin