Detailed explanation of spring AOP source code

MiaSanMiaRL 2022-01-27 01:06:53 阅读数:620

detailed explanation spring aop source

Spring Two powerful features are IOC as well as AOP, We know Spring Realization AOP The process is in SpringBean Processing in post processor , stay Bean Execute at initialization time , Let's take a detailed look at how the source code is done

  The methods of generating proxy objects will be delegated to InvocationHandler.Proxy perform , Let's first look at JdkDynamicAopProxy in invoke Method implementation

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;
Class var8;
try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
Boolean var18 = this.equals(args[0]);
return var18;
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer var17 = this.hashCode();
return var17;
if (method.getDeclaringClass() != DecoratingProxy.class) {
Object retVal;
if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
return retVal;
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
target = targetSource.getTarget();
Class<?> targetClass = target != null ? target.getClass() : null;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
} else {
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
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()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
Object var12 = retVal;
return var12;
var8 = AopProxyUtils.ultimateTargetClass(this.advised);
} finally {
if (target != null && !targetSource.isStatic()) {
if (setProxyContext) {
return var8;

Let's just look at a few important ways

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

Spring Realization AOP The responsibility chain model is used , And the function of this method is to obtain the chain

We can understand that , This chain is a collection of methods used to obtain and enhance the target object ( In order of execution ), If we get an empty chain , Then directly return to the original section , Return to the original object ; If so, trigger the interceptor chain ( The chain ) Implementation .

 MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();

Let's take another look proceed Method

public Object proceed() throws Throwable {
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
} else {
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);

We all know that there are actually five links of enhancement methods on the target method

Namely : The rear notice 、 Return to inform 、 Abnormal notice 、 Surrounding the notification 、 Pre notice

The order in which they trigger execution , That is, the order of addition is






our proceed Methods will first be in order , Determine whether we have configured the method of corresponding stage , If there is , Then execute the current enhancement method , without , The next method will be judged again through recursive call ; meanwhile , A count will be maintained on the chain , Used to manage the judged stage .

for instance

After we get the interceptor chain , First of all around Stage judgment

1、 We will first judge , stay around At this stage, I wonder if we have configured corresponding enhancement methods , here , Add one to the count of the chain , It means that we are about to enter the next stage of judgment .

2、 If in around There is an enhanced implementation of this method , Then execute the enhancement method .

3、 without , Recursively call proceed Method , Judgment of entering the next stage

Pay attention to this place , Here we use the judgment of recursive call into the method , in other words , After each stage of judgment , We'll go back to the interceptor chain , The interceptor tells us that we should enter that stage next time to judge .

The purpose of returning to the interceptor chain here is because we do not necessarily configure the enhancement methods in the established order in the configuration process , If the judgment is not specified by the interceptor chain , The sequence of stages will be disordered .

copyright:author[MiaSanMiaRL],Please bring the original link to reprint, thank you.