spring aop代码的增强

发布时间:2025-08-28 15:52

编写可读性强的注释提升代码质量 #生活技巧# #编程开发#

这篇博客,主要会分析spring aop是如何实现代码增强的。

从上一篇博客 我们大概知道,spring能在不改变代码的前提下,往一个方法的之前和之后添加代码。

想下,java中有哪种技术可以帮我们实现动态修改代码呢?就是jdk的动态代理。关于动态代理可以看下这篇博客jdk动态代理与cglib动态代理实现原理

大体我们先知道,jdk动态代理和cglib的动态代理都可以在运行时修改源码。两者之间的基本区别之一是,jdk动态代理需要被代理的类实现接口,cglib不需要。

然后我们开始分析spring是如何使用动态代理的。

回到spring调用链的图,spring 对于aop的增强是在创建bean时,通过BeanPostProcessor机制来实现的。在spring初始化之后类后,会有一次对类增强的机会。就是在AbstractAutoProxyCreator里。

AbstractAutoProxyCreator.postProcessAfterInitialization

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (!this.earlyProxyReferences.contains(cacheKey)) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean; }

这里就是检查下该类是否已经暴露过了(可能已经创建了,比如A依赖B时,创建A时候,就会先去创建B。当真正需要创建B时,就没必要再代理一次已经代理过的对象)

wrapIfNecessary

真正创建代理对象的地方就在wrapIfNecessary

依旧我们先来看最关键的一步,createProxy

protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);for (Advisor advisor : advisors) {proxyFactory.addAdvisor(advisor);}proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}//获取代理对象return proxyFactory.getProxy(getProxyClassLoader()); }

createProxy也很长,依旧我们只关心最重要的也就是最后一行,proxyFactory.getProxy

整理了一个流程图

大概说明下:
1)代理对象的创建最终委托给AopProxy生成
2)AopProxy的创建交由AopProxyFactory工厂
3)AopProxyFactory的默认实现是DefaultAopProxyFactory

AopProxyFactory.createAopProxy

那么我们先来看看AopProxy究竟是如何创建的。

我们首先可以看出,最后生成的AopProxy底层实现要么是cglib的,要么是jdk。再然后,我们分析下,什么时候使用jdk动态代理,什么时候使用cglib的。

1)配置了optimize。由于 cglib的动态代理创建类比较慢,但是执行代码比较快,jdk动态代理相反,创建比较快,执行比较慢。如果配置了optimize=true,那么目标类实现了接口就使用jdk代理,否则就用cglib。默认是false。
2)proxyTargetClass 是否强制使用cglib实现代理。默认是false
3)没有可代理的接口

代理对象的生成

到了这里,我们继续分析AopProxy如何生成代理对象(这里以jdk动态代理来分析)

看到Proxy.newProxyInstance就非常熟悉了,jdk的动态代理。

总结及待续

这篇博客大致分析了下,spring是如何创建代理对象的。jdk及cglib代理方式的选择。以及大概看了下jdk代理对象的创建。

当然还是留了很多问题,首先就是wrapIfNecessary里的各种缓存究竟是干啥用的,再然后就是jdk代理里,非常核心的InvocationHandler.invoke方法是如何实现的。再然后,我们常说的,切面,通知这些概念在源码层究竟对应着啥。这些问题会再下一篇博客介绍。

总结

以上是生活随笔为你收集整理的spring aop代码的增强的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。

网址:spring aop代码的增强 https://www.yuejiaxmz.com/news/view/1250044

相关内容

spring学习笔记 (3)aop的原理与实现
使用Spring AOP实现对外接口的日志自动打印
spring事务管理(详解和实例)
@EnableRetry(proxyTargetClass = true) . spring
Spring事务控制 @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class},)
Spring Boot 事务的简单使用
springboot整合AOP,实现log操作日志
【设计模式】代理模式
关于Spring 中的 IoC
stm32智能垃圾桶,功能具有感应翻盖,装满打包消毒(led灯亮表示),太阳能充电如何实现和会用到的代码

随便看看