文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring AOP 创建代理对象详情

2024-04-02 19:55

关注

1 前言

在这篇文章中中已经讲述了 AOP 的后置处理器和增强信息的获取,在本文中将继续分享 AOP 创建代理对象和上下文相关的内容。

2 创建代理对象

Spring AOP 使用 JDKProxy 和 CGLIB 两种方式来生成代理对象,具体使用哪一种需要根据 AopProxyFactory 接口的 createProxy 方法中的 AdvisedSupport 中的参数进行确定,默认情况下如果目标类是接口,则使用 jdk 动态代理技术,如果是非接口类,则使用 cglib 来生成代理。

在获取了所有对应 bean 的增强器之后,便可以进行代理的创建了,createProxy 方法。 对于代理类的创建以及处理,spring 委托给 ProxyFactory 进行处理,此方法主要进行初始化操作,并为代理工作做准备。主要分为以下步骤:

3 AOPContext Aop 上下文

在最终的代码调用中,还是 JdkDynamicAopProxy 的 invoke 方法和 CglibAopProxy 的 intercept 方法,以 CglibAopProxy 为例,可以看到 AopContext.setCurrentProxy 调用,将当前的对象设置到上下文中,在最后 finally 代码块中会将当前代理对象移除。

AOPContext 的主要方法如下图所示:

4 AOP 分析汇总

综上的逐步分析,最终总结的调用链路图如下所示,分为注册 Bean, 寻找增强器和创建代理等主要环节:

# 注册 bean
invokeBeanFactoryPostProcessors
 @EnableAspectJAutoProxy
 AspectJAutoProxyRegistrar.registerBeanDefinitions
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
AopConfigUtils.registerOrEscalateApcAsRequired
# 调用
finishBeanFactoryInitialization
AbstractAutoProxyCreator.postProcessAfterInitialization
AbstractAutoProxyCreator.wrapIfNecessary
AbstractAutoProxyCreator.getAdvicesAndAdvisorsForBean
AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean
AbstractAdvisorAutoProxyCreator.findEligibleAdvisors
AbstractAdvisorAutoProxyCreator.findCandidateAdvisors();
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors
BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors
ReflectiveAspectJAdvisorFactory.getAdvisors
ReflectiveAspectJAdvisorFactory.getPointcut 获取切点的注解信息
new InstantiationModelAwarePointcutAdvisorImpl
instantiateAdvice
ReflectiveAspectJAdvisorFactory.getAdvice 获取 advice
switch
AspectJAroundAdvice
AbstractAspectJAdvice.invokeAdviceMethod
AspectJMethodBeforeAdvice
AspectJAfterAdvice
AspectJAfterReturningAdvice
AspectJAfterThrowingAdvice
AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
AbstractAutoProxyCreator.createProxy
AbstractAutoProxyCreator.buildAdvisors
proxyFactory.getProxy(classLoader)
DefaultAopProxyFactory.createAopProxy
JdkDynamicAopProxy.getProxy
ObjenesisCglibAopProxy.getProxy

5 JDK 动态代理和 CGLIB 的区别与联系

在 Spring 中,如果说 IOC 和 DI 解决了类与类之间的耦合,那么动态代理则是解决了方法与方法,业务方法和切面逻辑之间的耦合。

JDK 动态代理只能对实现了接口类生成代理,而不能针对类进行代理。Cglib 是针对类进行代理,针对指定的类生成子类,并覆盖方法并进行增强,因为采用的是继承方式,所代理的类和方法不能是 final 修饰(final 的类或方法,是无法继承的)。

jdk 动态代理:创建一个实现 InvocationHandler 接口的拦截器,使用 Proxy.newProxyInstance() 反射机制生成一个代理对象,在具体调用方法之前先调用 InvokeHandler.invoke 来处理。

Cglib 动态代理:利用 ASM 字节码增强框架,对代理对象生成的 class 文件加载进来,通过修改字节码生成子类进行代理。

jdk 和 cglib 使用方法的区别:

综上, jdk 代理只能针对实现接口的类生成代理,而不能针对类。cglib 只能针对类进行代理。

6 总结

在本文中主要讲述了后置处理器和 AOP 的实现原理,以及 jdk 动态代理和 cglib 代理之间的区别,主要涉及增强获取和代理类的获取,以及后置处理器的理解。

到此这篇关于Spring AOP 创建代理对象详情的文章就介绍到这了,更多相关Spring AOP 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯