品牌型号:联想ThinkPad X1
系统:Windows10家庭版
软件版本:Spring 5.3.7
动态代理贯穿Spring框架多处核心功能,应用范围比大多数开发者认知的更广。不只是AOP这一处在用,Spring的事务管理能做到声明式,接口能做到无侵入式增强,背后都离不开动态代理,只不过我们写业务代码的时候很少会主动注意到这其实也是代理在背后起作用。另外,Spring框架内部到底有多少种动态代理技术呢?下面给大家介绍一下Spring哪些地方用到动态代理,Spring中有多少种动态代理的相关内容。
一、Spring哪些地方用到动态代理
经常要用到动态代理的地方就是AOP,像日志记录、权限校验、缓存处理这类横切逻辑,基本都是靠代理对象在方法调用前后插入额外处理实现的。

此外还有事务管理,严格意义上来说,它本身就是AOP思想的一个具体应用场景,加了@Transactional的方法,实际执行的并不是目标对象本身的方法,而是代理对象包装过的版本,事务的开启、提交、回滚这些动作,都是代理在背后悄悄完成的,我们在业务代码里完全看不到。

异步方法的处理也用到了代理机制,Spring里加了@Async注解的方法,调用的时候同样不是直接执行目标方法,而是先经过代理,代理负责把这个方法的执行投递至线程池异步执行,调用方拿到的是一个立即返回的结果或者Future对象,具体逻辑什么时候真正执行完,跟代理这层包装关系很大。

缓存相关的注解例如@Cacheable、@CacheEvict,原理也一样的,方法被调用时,代理会先判断缓存里有没有对应的数据,有就直接返回缓存结果,没有才真正去调用目标方法,执行完再把结果存进缓存。

二、Spring中有多少种动态代理
在Spring框架内部我们真正用到的动态代理技术主要就是JDK动态代理和CGLIB代理,这两种是Spring AOP模块直接依赖的实现方式,我们绝大多数场景都不会超出这两种实现。
像大家经常听到的AspectJ,它本身是一个独立于Spring的AOP框架,功能比Spring AOP全,它实现增强逻辑的方式不完全依赖运行时生成代理对象,而是有编译时织入和类加载时织入这两种更底层的手段,直接在字节码层面把切面逻辑嵌入到目标类里,不需要额外的代理对象包装一层。

当然,Spring也是支持跟AspectJ集成使用的,可以借助它的切点表达式语法,但这种集成更多是语法层面的复用,底层默认走的依然是JDK动态代理或CGLIB,只有显式开启AspectJ的织入功能时,我们才会真正用到它那套编译时或加载时处理的机制。

我们平时开发中接触到的,基本都是前两种,AspectJ的编译时织入用得相对少,一般出现在对性能、功能要求比较高,或者需要代理final类、private方法这类JDK和CGLIB都搞不定的特殊场景里。

以上就是Spring哪些地方用到动态代理,Spring中有多少种动态代理的全部内容了。代理这套机制在Spring里的应用比较广,像事务、异步、缓存这些常用功能背后基本都有代理在悄悄干活,只是平时我们在业务开发时很少会感知到底层代理的运行逻辑。Spring AOP默认依赖的还是JDK动态代理和CGLIB这两种,AspectJ的织入方式算是补充选项,大多数场景用不上。