0%

spring

spring bean 的生命周期,循环依赖的实现,IOC,AOP的原理,Spring MVC的请求处理流程

Spring Bean的生命周期

bean生命周期

为何需要三级缓存解决对象的循环依赖,二级缓存不行吗

Spring 使用三级缓存解决循环依赖的原因是为了支持AOP动态代理,如果只使用二级缓存,那么在AOP创建代理对象时,注入到其他bean的可能不是最终的代理对象而是原始的bean,这样会导致AOP失效或者出现异常。三级缓存的作用是在bean完成初始化后,但是没有放入到二级缓存之前,对bean进行动态代理的增强处理,并将代理对象放入二级缓存,同时将原先的代理对象从第三级缓存中删除,这样保证了注入到其他bean的都是经过AOP增强的同一个代理对象(默认是单例)。

Spring IOC的实现原理

IOC(控制反转)是依赖倒置原则的设计思路。将原先代码中需要实现的对象创建,对象依赖管理,交给IOC容器管理。

Spring IOC容器通过xml/注解方式来配置类和类之间的依赖关系,完成对象的创建和依赖管理,主要涉及到的模式就是工厂模式。

factory

IOC的优点

  • 集中管理对象的生命周期,实现类的可配置化,更容易管理对象之间的依赖关系
  • 降低类之间的耦合度

IOC做的事其实就是,低级容器(BeanFactory)加载配置文件,解析成BeanDefinition,然后放到一个map里,BeanName作为key ,这个Bean实例化的对象作为value, 使用的时候调用getBean方法,完成依赖注入。

至于高级容器 (ApplicationContext),它包含了低级容器的功能,当他执行 refresh 模板方法的时候,将刷新整个容器的 Bean。同时其作为高级容器,包含了太多的功能。一句话,他不仅仅是 IoC。他支持不同信息源头,支持 BeanFactory 工具类,支持层级容器,支持访问文件资源,支持事件发布通知,支持接口回调等等.

Spring AOP的实现原理

AOP面向切面编程的编程思想,是OOP编程的有效补充,使用AOP技术,可以将一些系统相关的代码提取出来通过切面进入系统,从而避免在业务逻辑代码中混入很多的系统相关的逻辑(日志记录,事务管理,权限控制等)。

AOP使用的优点:

  • 降低模块代码之间的耦合度
  • 系统更容易扩展
  • 提高代码的复用性

基本概念

  1. 连接点(JoinPoint):需要在程序中插入横切关注点的点,连接点可能是在类初始化、方法调用、字段调用或处理异常等等。Spring中只支持方法执行连接点。

  2. 切入点(Pointcut):一组相关连接点的集合。

  3. 通知(Advice):在连接点上执行的行为,增强提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段。包括前置增强(before advice)、后置增强 (after advice)、环绕增强 (around advice)。

  4. 切面(Aspect):通知和切入点的结合。

  5. 织入(Weaving):织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程。

  6. 代理(Proxy):通过代理方式来对目标对象应用切面。AOP代理可以用JDK动态代理或CGLIB代理实现。

  7. 目标对象(Target):需要被织入关注点的对象。即被代理的对象。

img

AOP的实现:

  • 静态代理:AspectJ ,在编译期间会添加AOP代码到Java类文件中。
  • 动态代理:JDK自带的动态代理和CGlib动态代理。

动态代理和静态代理,JDK自带的动态代理和CGlib的区别

动态代理的实现方式有两种,一种是基于接口的动态代理,另一种是基于类的动态代理。

  • 基于接口的动态代理,使用JDK官方的Proxy类创建代理对象,要求代理的目标对象必须实现接口。JDK动态代理是通过反射创建代理对象。
  • 基于类的动态代理使用CGlib的Enhancer类创建代理对象,可以对没有实现接口的类进行代理,原理是通过ASM字节码生成技术,运行期动态生成新的Class,创建原始类的子类,进而创建代理对象。

CGlib 的 FastClass 机制是一种优化方法,用于避免使用 Java 反射来调用目标类的方法。FastClass 机制的原理是:

  • CGlib 会为目标类和代理类各生成一个 FastClass 类,这个类会继承 FastClassByCGLIB 类,并且包含一个 invoke 方法。
  • invoke 方法的参数是一个整数 index,一个对象数组 args 和一个 Class[] types。index 表示要调用的目标类或代理类的方法编号,args 表示要传递的参数,types 表示参数的类型。
  • invoke 方法会根据 index 和 types 来确定要调用的具体方法,并且使用强制类型转换和硬编码的方式来直接调用该方法,而不需要通过反射。
  • CGlib 会为每个方法生成一个唯一的 index,并且在 FastClass 类中维护一个数组来存储这些 index。这样就可以通过 index 快速定位到要调用的方法。

反向代理和正向代理

正向代理中,Proxy和client属于一个LAN,对于server端来讲是透明的。

反向代理中,Proxy和server同属一个LAN,对于客户端来讲是透明的。

正向代理可以用来访问客户端无法访问的资源,可以做缓存加速,客户端授权认证。

反向代理可以用来做负载均衡,保护server端的安全,组织web攻击。

img

Spring MVC请求的处理流程

前端请求发送到DispatchServlet,DispatchServlet负责转发请求到HandlerMapping,从handlerMapping中获取到handle,然后通过handler获取handlerAdapter,根据适配器执行handler方法(业务方法),返回modelAndView对象,之后通过ViewResolver解析ModelAndView返回页面。主要在获取 handlerAdapter 后,会先执行拦截器方法,然后才执行真正的handler 方法。

img

参考资料:

理解Spring的AOP和IOC实现原理 - 简书 (jianshu.com)

https://juejin.cn/post/6963589313317568543

Spring 为何需要三级缓存解决循环依赖? - 掘金 (juejin.cn)