浅析AOP源码

  AOP(Aspect-Oriented Programming)面向切面的编程,在平时的开发过程中,AOP其实用到的地方一般有:

①用来做日记的处理
②方法的调用统计
③业务层面的读写分离(例如自定义的Annotation+AOP可以实现切换数据源)
④自定义权限拦截器

  在Spring框架中,AOP则发挥了不少功效,例如spring的事务。
  AOP具体的介绍移步:https://blog.csdn.net/zero__007/article/details/46765191


  在介绍代码之前先介绍Spring Aop中一些核心类,大致分为三类:
  advisor:顾问的意思,advisor是Spring中切面的体现形式,封装了spring aop中的切点和通知。包括有:

DefaultPointcutAdvisor: 默认切面顾问,比较灵活。可自由组合切面和通知。
InstantiationModelAwarePointcutAdvisorImpl: springboot自动装配的顾问类型,也是最常用的一种顾问实现。在注解实现的切面中,所有@Aspect注释的类,都会被解析成该对象。

  advice:通知,也就是 Spring AOP 中增强的方法。包括有:

AspectJMethodBeforeAdvice:前置通知,AspectJ中 before 属性对应的通知(@Before标注的方法会被解析成该通知),在切面方法执行之前执行。
AspectJAfterReturningAdvice:后置通知,AspectJ中 afterReturning 属性对应的通知(@AfterReturning 标注的方法会被解析成该通知),在切面方法执行之后执行,如果有异常,则不执行。注意:该通知与AspectJMethodBeforeAdvice对应。
AspectJAroundAdvice:环绕通知,AspectJ中 around 属性对应的通知(@Around标注的方法会被解析成该通知),在切面方法执行前后执行。
AspectJAfterAdvice:返回通知,AspectJ中 after 属性对应的通知(@After 标注的方法会被解析成该通知),不论是否异常都会执行。

  advisorCreator:代理机制,抽象类AbstractAutoProxyCreator的每个实现类代表着一种代理机制。默认情况下只使用一种代理机制。 继承 spring ioc的扩展接口 beanPostProcessor,主要用来扫描获取 advisor。包括有:

AbstractAutoProxyCreator:代理机制抽象类,Spring 为Spring AOP 模块暴露的扩展类,也是 AOP 中最核心的类。Nepxion Matrix 框架便是基于此类对AOP进行扩展和增强。
AspectJAwareAdvisorAutoProxyCreator:Aspectj的实现方式,也是Spring Aop中最常用的实现方式,如果用注解方式,则用其子类AnnotationAwareAspectJAutoProxyCreator。
AnnotationAwareAspectJAutoProxyCreator:目前最常用的AOP使用方式。spring aop 开启注解方式之后,该类会扫描所有@Aspect()标准的类,生成对应的adviosr。目前SpringBoot框架中默认支持的方式,自动配置。


  在Spring中,使用AOP需要在xml中添加 Aop:configAop:aspectj-autoproxy 标签。Spring会使用AopNamespaceHandler#init注册这类标签解析器beanDefinitionparser:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class AopNamespaceHandler extends NamespaceHandlerSupport {

/**
* Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
* '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
* and '{@code scoped-proxy}' tags.
*/
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}

}

  AspectJAutoProxyBeanDefinitionParserConfigBeanDefinitionParser都是BeanDefinitionParser的子类。
  在解析为BeanDefinition时,BeanDefinitionParserDelegate#parseCustomElement会调用到这个BeanDefinitionParser的parse方法:

1
2
3
4
5
6
7
8
9
10
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = this.getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
} else {
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}

  来关注看下AspectJAutoProxyBeanDefinitionParser

1
2
3
4
5
6
7
8
9
10
11
12
13
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {

@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//解析aspectj-autoproxy标签
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//解析子标签
extendBeanDefinition(element, parserContext);
return null;
}

// …
}

  AopNamespaceUtils类:

1
2
3
4
5
6
7
8
9
10
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//注册bean:AnnotationAwareAspectJAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//设置proxy-target-class和expose-proxy这两个属性
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//注册到ParserContext
registerComponentIfNecessary(beanDefinition, parserContext);
}

  下面是关键类AnnotationAwareAspectJAutoProxyCreator
在这里插入图片描述  AnnotationAwareAspectJAutoProxyCreator继承了SmartInstantiationAwareBeanPostProcessorAbstractAutoProxyCreator中对SmartInstantiationAwareBeanPostProcessor的接口有实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
// ...

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);

if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
//advisedBeans用于存储不可代理的bean,如果包含直接返回
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//isInfrastructureClass判断是否是Advisor、Advice、AopInfrastructureBean,如果是,则不能被代理
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}

//到这里说明该bean可以被代理,所以去获取自定义目标类,如果没有定义,则跳过。
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
//获取bean适配的Advice
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//创建代理
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
//如果最终可以获得代理类,则返回代理类,直接执行实例化后置通知方法
return proxy;
}
}

return null;
}

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}

@Override
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;
}

//…
}

  在bean实例化前和后会调用SmartInstantiationAwareBeanPostProcessor接口方法,看代码注释就大致知道是什么过程。来看 shouldSkip 方法,shouldSkip会跳过切面类,怎么判定呢?在子类AspectJAwareAdvisorAutoProxyCreator中:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}

  通过findCandidateAdvisors()方法来获取所有的候选 advisor:

1
2
3
4
5
6
7
8
@Override
protected List<Advisor> findCandidateAdvisors() {
//获得 Advisor 实现类
List<Advisor> advisors = super.findCandidateAdvisors();
// 处理@Aspect注解类, 解析成Advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}

  buildAspectJAdvisors()方法会解析@Aspect注解类,将该类所有被@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut注解的方法封装成advisor。

  可以看出来,创建advisor的逻辑发生在扩展接口中的postProcessBeforeInstantiation,实例化之前执行,如果有自定义的TargetSource指定类,则直接生成代理类,这种情况使用不多,常规代理类还是在postProcessAfterInitialization中创建,也就是 IOC 最后一个扩展方法。
  在bean实例化之后,调用postProcessAfterInitialization()来生成代理类,来看下里面的wrapIfNecessary()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

//获取适合的advise
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理类
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

  先获取到合适的advisor,如果不为空,则调用createProxy生成代理类。

createProxy()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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());
}

  首先会创建一个ProxyFactory对象:

1
public class ProxyFactory extends ProxyCreatorSupport {
1
2
3
4
5
6
7
public class ProxyCreatorSupport extends AdvisedSupport {

private AopProxyFactory aopProxyFactory;

public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}

  AopProxyFactory是一个接口,用生成AopProxy:

1
2
3
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}

  AopProxy也是一个接口类,它的实现类有CglibAopProxyJdkDynamicAopProxyObjenesisCglibAopProxy

  
  继续看ProxyFactory#getProxy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}

protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

  在DefaultAopProxyFactory#createAopProxy中,会决定是jdk代理还是cglib代理:
  • optimize:代理是否应执行积极的优化,默认为false。
  • proxyTargetClass:AopAutoConfiguration中指定,默认为true,也就是选择使用 cglib 代理。proxyTargetClass=true设定
  • hasNoUserSuppliedProxyInterfaces:是否没有实现接口

JdkDynamicAopProxy

  Spring提供了多种方式来生成代理对象,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,否则使用Cglib来生成代理。
  下面看一下Spring如何使用JDK来生成代理对象,具体的生成代码在JdkDynamicAopProxy这个类中:

1
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

  InvocationHandler是JDK动态代理的核心,生成的代理对象的方法调用都会委托到InvocationHandler.invoke()方法。分析一下这个类中实现的invoke()方法来具体看下Spring AOP是如何织入切面的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;

try {
// ……

Object retVal;

if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// May be null. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 获得目标对象的类
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}

// Get the interception chain for this method.
// 获取可以应用到此方法上的Interceptor列表
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
// 如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建MethodInvocation
// 整个拦截链的工作逻辑都在这个ReflectiveMethodInvocation里
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}

//……
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

  主流程可以简述为:获取可以应用到此方法上的通知链(Interceptor Chain),如果有,则应用通知,并执行joinpoint; 如果没有,则直接反射执行joinpoint。而这里的关键是通知链是如何获取的以及它又是如何执行的。通知链是通过Advised#getInterceptorsAndDynamicInterceptionAdvice()这个方法来获取的:

1
2
3
4
5
6
7
8
9
10
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}

  实际的获取工作其实是由DefaultAdvisorChainFactory# getInterceptorsAndDynamicInterceptionAdvice()这个方法来完成的,获取到的结果会被缓存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
   /** 
* 从提供的配置实例config中获取advisor列表,遍历处理这些advisor.如果是IntroductionAdvisor,
* 则判断此Advisor能否应用到目标类targetClass上.如果是PointcutAdvisor,则判断
* 此Advisor能否应用到目标方法method上.将满足条件的Advisor通过AdvisorAdaptor转化成Interceptor列表返回.
*/
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {

List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);

//查看是否包含IntroductionAdvisor
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);

//这里实际上注册一系列AdvisorAdapter,用于将Advisor转化成MethodInterceptor
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

for (Advisor advisor : config.getAdvisors()) {

if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//检查当前advisor的pointcut是否可以匹配当前方法
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}

return interceptorList;
}

​ 第19行 for (Advisor advisor : config.getAdvisors()) , config.getAdvisors()返回的就是定义好的Advisor列表。registry.getInterceptors(advisor)是把advisor转换成MethodInterceptor[]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}

​ AdvisorAdapter的实例有AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter分别用于转换AfterReturningAdvice、MethodBeforeAdvice、ThrowsAdvice为AfterReturningAdviceInterceptor、MethodBeforeAdviceInterceptor、ThrowsAdviceInterceptor。

  得到的拦截器链后,如果拦截器链为空,则直接反射调用目标方法,否则创建MethodInvocation,调用其proceed方法,触发拦截器链的执行,来看下具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//如果Interceptor执行完了,则执行joinPoint
return invokeJoinpoint();
}
// 取得第拦截器链上第N个拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

//如果要动态匹配joinPoint
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//动态匹配:运行时参数是否满足匹配条件
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//执行当前Intercetpor
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//执行当前Intercetpor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

  在使用Spring AOP的时候,一般是不需要选择具体的实现方式的。Spring AOP能根据上下文环境帮助我们选择一种合适的。强制使用CGLIB很简单:
  @EnableAspectJAutoProxy(proxyTargetClass = true)
  向@EnableAspectJAutoProxy注解中添加属性proxyTargetClass = true即可。


转载自:
https://blog.csdn.net/moreevan/article/details/11977115/
https://blog.csdn.net/qq_38182963/article/details/78747404
https://blog.csdn.net/moreevan/article/details/11977115/
https://blog.csdn.net/qq_38182963/article/details/78747404
https://blog.csdn.net/xiaoxufox/article/details/54695200
https://mp.weixin.qq.com/s?__biz=MzAxNjk4ODE4OQ==&mid=2247484741&idx=1&sn=42310e59d06abc3fa08454949e3a17aa&chksm=9bed2437ac9aad21cb5e635bef607e1c0631ea9e8ca88fed8f65ecb61ca69f1951679d84ee41&scene=21#wechat_redirect