亲宝软件园·资讯

展开

Spring AOP

​ 斜月   ​ 人气:0

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 代理之间的区别,主要涉及增强获取和代理类的获取,以及后置处理器的理解。

加载全部内容

相关教程
猜你喜欢
用户评论