【源码解析】Spring AOP
前言:📫 作者简介:小明java问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫
🏆 Java领域优质创作者、阿里云专家博主、华为云专家🏆
🔥 如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦
一、总的来聊 AOP 概念,应用场景,动态代理
【直接开始背诵并默写,抛出 AOP 概念,应用场景,动态代理】
【AOP概念、应用】AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术。AOP 是 IOC 的一个扩展功能,先有的 IOC ,再有的AOP,只是在 IOC 的整个流程中新增的一个扩展点而已,在调用BeanPostProcessor 的后置处理方法实现。当我们需要为多个不具有继承关系的对象引入一个公共行为,例如日志、权限管理、事务等功能时,只能在在每个对象里引用公共行为。AOP便做这种不便于维护,而且有大量重复代码的事情。
【AOP实现-动态代理源码分析】一般我们会将切面类声明为一个bean,切点指定的方法所在的类也同样需由Spring 注入。Spring的@EnableAspectJAutoProxy 给容器beanFactory 中注册一个AnnotationAwareAspectJAutoProxyCreator对象;AnnotationAwareAspectJAutoProxyCreator对目标对象进行代理对象的创建,对象内部,是封装JDK和CGlib 两个技术,实现动态代理对象创建的(创建代理对象过程中,会先创建一个代理工厂,获取到所有的增强器(通知方法),将这些增强器和目标类注入代理工厂,再用代理工厂创建对象);其中JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类:Proxy 和 InvocationHandler。Proxy 利用 InvocationHandler(定义横切逻辑) 接口动态创建 目标类的代理对象。代理对象执行目标方法,得到目标方法的拦截器链,利用拦截器的链式机制,依次进入每一个拦截器进行执行。最终通过 getProxy() 【后面详细说】方法来获取代理对象。
二、展开说AOP 实现过程
【展开说AOP(AOP Proxy)实现过程、AOP代理对象的生成、织入(Weaving)切面】
【*实现过程*】AOP实现过程在IOC中,首先创建一个新的 ApplicationContext,加载bean并自动刷新上下文,在AbstractApplicationContext的 refresh() 方法中加载或刷新容器,通过AbstractApplicationContext 的finishBeanFactoryInitialization() 方法完成bean工厂的初始化和所有的单例bean;ConfigurableListableBeanFactory#preInstantiateSingletons() 方法 确保所有非lazyinit单例都被实例化;在AbstractBeanFactory 的 getBean(java.lang.String)方法,返回一个可以共享或独立于指定bean的实例,最后在AbstractBeanFactory#createBean() 方法创建bean。AbstractAutowireCapableBeanFactory#initializeBean() 方法,进行工厂回调、init方法和bean后处理器初始化给定的bean。
下面进入AOP 代理对象的创建,在AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsAfterInitialization() 方法,将 BeanPostProcessor 应用到给定的现有bean实例中,调用它们的代码后置处理初始化方法。返回的bean实例可以是围绕原始的包装器。在AbstractAutoProxyCreator 【对目标对象进行代理对象的创建,对象内部,是封装JDK和CGlib两个技术】的 postProcessAfterInitialization() 方法中,如果子类将bean标识为一个代理,则使用配置的侦听器创建一个代理;进入AbstractAutoProxyCreator的 wrapIfNecessary() 方法,包装给定的有资格代理的bean,在 AbstractAutoProxyCreator中的 createProxy() 会为给定的bean创建AOP代理,在 ProxyFactory工厂中getProxy(java.lang.ClassLoader)【后面详细说】,会根据此工厂中的设置创建新代理对象,最后DefaultAopProxyFactory#createAopProxy() 方法,创建给定的AOP代理工厂实例。
【实在解释不明白就直接画图,跳过上面的直接说,生成和织入】
【*AOP代理对象的生成*】
AOP代理对象的生成,这里面在 ProxyFactory工厂中getProxy(java.lang.ClassLoader),获取代理类要实现的接口,除了Advised对象中配置的,还会加上SpringProxy, Advised(opaque=false),检查上面得到的接口中有没有定义 equals或者hashcode的接口,调用Proxy.newProxyInstance创建代理对象
【getProxy源码,了解即可,背诵上述文字描述】
【*织入AOP切面*】
织入AOP切面在InvocationHandler,InvocationHandler 是JDK动态代理的核心,生成的代理对象的方法调用都会委托到InvocationHandler.invoke()方法。invoke() 方法,获取可以应用到此方法上的通知链(Interceptor Chain),依次进入每一个拦截器进行执行,如果有,则应用通知,并执行joinpoint;如果没有,则直接反射执行joinpoint。最终通过 getProxy() 方法来获取代理对象。
【invoke源码,了解即可,背诵上述文字描述】
- 点赞
- 收藏
- 关注作者
评论(0)