参考文章:
前文:
写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。
目录
4、ReflectiveMethodInvocation#proceed
1、AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
2、DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
3、GlobalAdvisorAdapterRegistry
4、DefaultAdvisorAdapterRegistry
4.1、DefaultAdvisorAdapterRegistry
在前文中,我们找到了所有适用于当前bean的增强器,本文我们就为他们创建适用于他们的代理类。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1.判断当前bean是否在targetSourcedBeans缓存中存在(已经处理过),如果存在,则直接返回当前bean
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 2.在advisedBeans缓存中存在,并且value为false,则代表无需处理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 4.获取当前bean的Advices和Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 5.如果存在增强器则创建代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 5.1 创建代理对象:这边SingletonTargetSource的target属性存放的就是我们原来的bean实例(也就是被代理对象),
// 用于最后增加逻辑执行完毕后,通过反射执行我们真正的方法时使用(method.invoke(bean, args))
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 5.2 创建完代理后,将cacheKey -> 代理类的class放到缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理对象
return proxy;
}
// 6.标记为无需处理
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
一、createProxy
1、createProxy
在生成代理类之前,主要做了两件事,判断使用 Jdk 代理还是 Cglib 代理以及设置相关的属性。
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
// 如果当前beanFactory实现了ConfigurableListableBeanFactory接口,则将需要被代理的对象暴露出来
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 从当前对象复制属性值
proxyFactory.copyFrom(this);
// 检查proxyTargetClass属性,判断对于给定的bean使用类代理还是接口代理,
// proxyTargetClass值默认为false,可以通过proxy-target-class属性设置为true
if (!proxyFactory.isProxyTargetClass()) {
// 检查preserveTargetClass属性,判断beanClass是应该基于类代理还是基于接口代理
if (shouldProxyTargetClass(beanClass, beanName)) {
// 如果是基于类代理,则将proxyTargetClass赋值为true
proxyFactory.setProxyTargetClass(true);
} else {
// 判断目标类是否实现了相关接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将拦截器封装为Advisor(advice持有者)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 将advisors添加到proxyFactory
proxyFactory.addAdvisors(advisors);
// 设置要代理的类,将targetSource赋值给proxyFactory的targetSource属性,之后可以通过该属性拿到被代理的bean的实例
proxyFactory.setTargetSource(targetSource);
// 自定义ProxyFactory,空方法,留给子类实现
customizeProxyFactory(proxyFactory);
// 用来控制proxyFactory被配置之后,是否还允许修改通知。默认值为false(即在代理被配置之后,不允许修改代理类的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 使用proxyFactory生成代理
return proxyFactory.getProxy(getProxyClassLoader());
}
2、getProxy
可以理解为一个工厂方法,返回值是一个 AopProxy 类型的对象,其内部根据具体的条件生成相应的子类对象,即 JdkDynamicAopProxy 和 ObjenesisCglibAopProxy。后面则通过调用 AopProxy.getProxy() 方法获取代理过的对象。
public Object getProxy(ClassLoader classLoader) {
// 首先创建AopProxy对象,其主要有两个实现:JdkDynamicAopProxy和ObjenesisCglibAopProxy,
// 分别用于Jdk和Cglib代理类的生成,其getProxy()方法则用于获取具体的代理对象
return createAopProxy().getProxy(classLoader);
}
3、createAopProxy
真正创建了AopProxy的实现类,根据不同的条件判断是创建JdkDynamicAopProxy 还是 ObjenesisCglibAopProxy,这两个分别对应了JDK与CGLIB的代理类生成方式。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
// 1.激活此代理配置
activate();
}
// 2.创建AopProxy
return getAopProxyFactory().createAopProxy(this);
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 1.判断使用JDK动态代理还是Cglib代理
// optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,
// 否则不推荐使用这个配置,目前这个属性仅用于cglib代理,对jdk动态代理无效
// proxyTargetClass:默认为false,设置为true时,强制使用cglib代理,设置方式:<aop:aspectj-autoproxy proxy-target-class="true" />
// hasNoUserSuppliedProxyInterfaces:config是否存在代理接口或者只有SpringProxy一个接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 拿到要被代理的对象的类型
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
// TargetSource无法确定目标类:代理创建需要接口或目标。
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 如果被代理的类是一个接口,或者被代理的类是使用Jdk代理生成的类,此时还是使用Jdk代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
// JDK动态代理,这边的入参config(AdvisedSupport)实际上是ProxyFactory对象
return new JdkDynamicAopProxy(config);
}
// Cglib代理
return new ObjenesisCglibAopProxy(config);
} else {
// JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
二、JdkDynamicAopProxy
1、JdkDynamicAopProxy
JdkDynamicAopProxy的构造方法,内容很简单,就是将之前创建的ProxyFactory对象赋值给成员变量advised。
// JdkDynamicAopProxy.java
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
// config赋值给advised
this.advised = config;
}
2、getProxy
(1)获取生成代理对象所需要实现的所有接口
(2)然后判断接口中是否包含有 equals () 和 hashCode () 方法,因为这将用于判断生成的代理类是使用用于定义的 equals () 和 hashCode () 方法还是使用自动生成的方法
(3)通过动态代理生成代理对象
这里需要注意的是 JdkDynamicAopProxy 不仅实现了 AopProxy 接口还实现了 InvocationHandler 接口,因而这里生成代理对象的时候传入的 InvocationHandler 对象是 this。
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
// 拿到要被代理对象的所有接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 找到接口中是否包含有equals()和hashCode()方法,并进行标识
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 通过classLoader、接口、InvocationHandler实现类生成代理对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
到这里,使用JDK动态代理创建的代理类已经完成了,当JDK动态代理的类被调用时,会走到 JdkDynamicAopProxy#invoke 方法。
3、invoke
判断目标方法是否为 Spring 织入的 Advised 中的方法,如果是,则调用当前 advised 对象中相应的方法。然后就会获取当前方法需要织入的代理逻辑的调用链。接着就会将目标对象和调用链逻辑封装为 ReflectiveMethodInvocation,并进行调用。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
// advised就是proxyFactory,而targetSource持有被代理对象的引用
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// 如果当前方法是equals()方法,并且接口中并未定义该方法,就使用自动生成的equals()方法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// 如果当前方法是hashCode()方法,并且接口中并未定义该方法,就使用自动生成的hashCode()方法
return hashCode();
} else if (method.getDeclaringClass() == DecoratingProxy.class) {
// 如果当前方法是Spring织入的DecoratingProxy接口中的方法,则返回目标对象的Class类型
return AopProxyUtils.ultimateTargetClass(this.advised);
} else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 如果当前方法是Spring织入的Advised接口中的方法,则使用反射调用当前advised对象中的相关方法
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
// 如果设置了需要暴露代理对象,则将当前对象设置到AopContext中
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 拿到我们被代理的对象实例
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// 获取当前方法需要织入的切面逻辑的调用链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 检查我们是否有任何拦截器(advice)。 如果没有,直接反射调用目标,并避免创建MethodInvocation。
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 不存在拦截器链,则直接进行反射调用
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
// We need to create a method invocation...
// 如果存在拦截器,则创建一个ReflectiveMethodInvocation:代理对象、被代理对象、方法、参数、
// 被代理对象的Class、拦截器链作为参数创建ReflectiveMethodInvocation
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 触发ReflectiveMethodInvocation的执行方法
retVal = invocation.proceed();
}
// 必要时转换返回值
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// 判断返回值如果为目标对象,并且当前方法的返回值类型是当前代理对象的类型,那么就将
// 当前代理对象返回。这里的逻辑的实际意思简单的说就是,如果返回值是目标对象,那么
// 就将当前代理对象返回
retVal = proxy;
} else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
// 如果返回值满足其为空,不是Void类型,并且是基本数据类型,那么就抛出异常,
// 因为基本数据类型的返回值必然不为空
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
} finally {
if (target != null && !targetSource.isStatic()) {
// 如果TargetSource不是静态的,则调用其releaseTarget()方法将生成的目标对象释放
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// 处理AopContext中保存的当前代理对象
AopContext.setCurrentProxy(oldProxy);
}
}
}
4、ReflectiveMethodInvocation#proceed
ReflectiveMethodInvocation对象包含代理对象、被代理对象、方法、参数、被代理对象的 Class、拦截器链等。
protected ReflectiveMethodInvocation(
Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
ReflectiveMethodInvocation#proceed()为责任链方法,会按索引执行所有的拦截器。
如果所有拦截器都执行完毕(index是从-1开始,所以跟size - 1比较),则直接使用反射调用连接点(也就是我们原本的方法)。
如果是一个普通的拦截器,则直接调用它,参数为自己本身。
@Override
public Object proceed() throws Throwable {
// 1.如果所有拦截器都执行完毕(index是从-1开始,所以跟size - 1比较),则直接使用反射调用连接点(也就是我们原本的方法)
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 2.每次调用时,将索引的值递增,并通过索引拿到要执行的拦截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 3.判断拦截器是否为InterceptorAndDynamicMethodMatcher类型(动态方法匹配拦截器)
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 进行动态匹配。在此评估动态方法匹配器:静态部件已经过评估并且发现匹配。
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// 动态匹配失败。跳过此拦截器并调用链中的下一个。
return proceed();
}
} else {
// 4.只是一个普通的拦截器,则触发拦截器链责任链的调用,并且参数为ReflectiveMethodInvocation本身
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
二、invoke
1、AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice
先来看看拦截器链是怎么生成的,getInterceptorsAndDynamicInterceptionAdvice方法取得拦截器链的工作是由配置好的advisorChainFactory来完成的,从名字上可以猜到,它是一个生成通知器链的工厂。在这里,advisorChainFactory被配置成一个DefaultAdivsorChainFactory对象,在DefaultAdivsorChainFactory 中实现了interceptor链的获取过程。
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;
}
2、DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
首先会获取一个AdvisorAdapterRegistry对象,这个对象负责实现拦截器的注册。
有了AdvisorAdapterRegistry注册器,利用它来从ProxyFactoryBean 配置中得到的通知进行适配,从而获取相应的拦截器,完成所谓的拦截器注册过程。在拦截器适配和注册完成以后,拦截器会被JDK生成AopProxy代理对象的invoke方法或者CGLIB代理对象的intercept拦截方法取得,并启动拦截器的invoke调用,最终触发通知的切面增强。
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
//全局获取AdvisorAdapterRegistry实例
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
// 匹配当前方法
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
// 适配advisor成方法拦截器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
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;
}
3、GlobalAdvisorAdapterRegistry
GlobalAdvisorAdapterRegistry.getInstance()其实就是实例化了一个DefaultAdvisorAdapterRegistry对象。
public abstract class GlobalAdvisorAdapterRegistry {
private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();
public static AdvisorAdapterRegistry getInstance() {return instance;}
static void reset() {instance = new DefaultAdvisorAdapterRegistry();}
}
4、DefaultAdvisorAdapterRegistry
4.1、DefaultAdvisorAdapterRegistry
DefaultAdvisorAdapterRegistry对象的构造方法注册了MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter这三个适配器对象。
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
4.2、getInterceptors
我们回到上文中的registry.getInterceptors(advisor),该方法也是由这个类实现的。
可以看出该方法会根据传入的advice增强器是否是MethodInterceptor类型,如果是的话则直接加入集合中,并判断构造方法中注册的适配器是否支持当前的advice,如果支持调用适配器的getInterceptor然后加入到返回集合中。
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
//从Advisor通知配置中取得advice通知
Advice advice = advisor.getAdvice();
//如果是MethodInterceptor类型,不需要再适配,直接加入集合
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 对adice进行适配
for (AdvisorAdapter adapter : this.adapters) {
//适配器支持当前adive
if (adapter.supportsAdvice(advice)) {
// 适配并返回结果
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
以@Before为例,supports方法判断是否为MethodBeforeAdvice类型,是的话则支持。而getInterceptor方法则是把advice从advisor 中取出,然后创建一个MethodBeforeAdviceInterceptor 对象,通过这个对象把advice包装起来,完成适配过程。
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
// 判断advice增强器是否是MethodBeforeAdvice类型
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
相关的增强器我们在前文中已经介绍过了,这里不做赘述。
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
5、invoke
上文中ReflectiveMethodInvocation#proceed方法中判断如果只是一个普通的拦截器,则触发拦截器链责任链的调用,并且参数为ReflectiveMethodInvocation本身。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
还是以@Before为例,其invoke方法由于MethodBeforeAdviceInterceptor类实现,该类的invoke方法再调用AspectJMethodBeforeAdvice类的before方法,然后便会执行被增强方法。
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
再比如@After的实现,则是基于MethodInterceptor接口的invoke方法,比如当增强类型为@After时,调用AspectJAfterAdvice的invoke方法,不过这里需要注意的是这里是先return,执行责任链的下一个增强器,最后再执行增强方法invokeAdviceMethod。
//AspectJAfterAdvice.java
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
6、invokeJoinpoint
invokeJoinpoint负责反射执行连接点,也就是原方法。
protected Object invokeJoinpoint() throws Throwable {
// 反射执行连接点,也就是原方法,target为被代理的对象实例、method为执行的方法、arguments为方法参数
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
// 使用反射调用方法
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
} catch (InvocationTargetException ex) {
throw ex.getTargetException();
} catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
} catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
以上,基于@AspectJ注解实现的AOP原理基本介绍完毕,整体流程基本整理如下:
(1)使用<aop:aspectj-autoproxy/>开启AOP注解解析,并注册对应的内部管理的自动代理创建者的 bean:AnnotationAwareAspectJAutoProxyCreator。
(2)容器创建bean到初始化阶段时,调用postProcessAfterInitialization 方法,此时调用此时就会调用我们的 AnnotationAwareAspectJAutoProxyCreator类重写的该方法,然后先查询出所有的增强器(即@Before、@After、@Around 等注解),并根据 @Pointcut 的 execution 表达式筛选出适用于当前遍历的 bean 的增强器, 将适用于当前遍历的 bean 的增强器作为参数之一创建对应的 AOP 代理。
(3)当调用到被 AOP 代理的方法时,会走到对应的代理方法:JdkDynamicAopProxy#invoke 或 DynamicAdvisedInterceptor#intercept,该方法会创建 ReflectiveMethodInvocation,通过责任链的方式来执行所有的增强器和被代理的方法。