通过第一篇文章我们已经知道了怎么生成代理对象,现在这篇文章我们来跟踪下源码怎么执行代理方法。一个简单的例子来探寻SpringAOP执行源码的主脉络(一):创建代理对象
我们调试可以发现,我们的代理对象内容如下
里面有两个Advisor,第一个应该是spring默认的,我们定义的增强器为
InstantiationModelAwarePointcutAdvisor
这个也就对应我们的
@Aspect
@Component
public class MyAspect {
@Pointcut("execution(public * com.suibibk.spring.service.*.*(..))")
public void web() {
}
@Around("web()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("之前");
Object obj =pjp.proceed();
System.out.println("之后");
return obj;
}
}
里面的doAround方法,是这个方法的包装。我们点击下一步,进入到这个代里对象的invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//这个如果开启表明会将当前代理对象放到当前西线程中,然后你在当前方法中就可以获取当前的代理对象了。
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// Get the interception chain for this method.
//这里就是获取两个增强器,第二个才是我们要的
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.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// We need to create a method invocation...
//把全部信息都封装成一个MethodInvocation对象,然后调用proceed方法。
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
上面关键步骤都有中文注释,主要就是获取Advisor链,然后封装成一个MethodInvocation对象。我们调试进去。
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//这里是递归的返回出口
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//这里是获取当前的一个下标,也就是先加1,一开始是-1
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
//这里把当前类对象传过去
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
这里通过用巧妙的方式,把循环去掉,变成递归。其实就是记录一个下标,没执行一个Advisor就自增一次,等所有Advisor都执行完了后,才会去调用正真的被代理对象的业务逻辑方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
我们发现我们的Advisor不是InterceptorAndDynamicMethodMatcher,所以会进入后面的方法
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
这里执行完业务操作后又调用了
return mi.proceed();
又回到了上面的方法,不过此时currentInterceptorIndex==0,所以自加后会取到第二个,第二个是我们的切面方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
if (!(mi instanceof ProxyMethodInvocation)) {
throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
}
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
JoinPointMatch jpm = getJoinPointMatch(pmi);
return invokeAdviceMethod(pjp, jpm, null, null);
}
我们进到
invokeAdviceMethod(pjp, jpm, null, null);
看看是怎么执行我们的
@Around("web()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("之前");
Object obj =pjp.proceed();
System.out.println("之后");
return obj;
}
方法的
protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch,
@Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
我们进入到
invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}
try {
ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
// TODO AopUtils.invokeJoinpointUsingReflection
//应该是在这里执行的
return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("Mismatch on arguments to advice method [" +
this.aspectJAdviceMethod + "]; pointcut expression [" +
this.pointcut.getPointcutExpression() + "]", ex);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
});
aspectJAdviceMethod这个就是我们的doAround方法,这里是执行这个方法。这一个方法运行会跳到我们的
@Around("web()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("之前");
Object obj =pjp.proceed();
System.out.println("之后");
return obj;
}
执行第一条语句答应后会取执行我们的proceed()方法,这里会去执行我们的test()方法,然后又会跳到
//这里是递归的返回出口
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
这里的invokeJoinpoint()就是执行我们正真的方法
@Nullable
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
@Nullable
public static Object invokeJoinpointUsingReflection(@Nullable 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) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
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);
}
}
执行完业务逻辑后又会跳回
@Around("web()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("之前");
Object obj =pjp.proceed();
System.out.println("之后");
return obj;
}
打印”之后”然后返回。然后就执行完了,总体来说还是比较简单的。
总之:主要的业务处理考的是每个Advisor里面的advice(通知)的invoke方法。所以后面我们看事务的代理对象执行逻辑也只需要看它的advisor里面的advice的invoke方法就可以了。