视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Spring源代码解析(七):Spring AOP中对调用的实现
2025-09-29 08:42:02 责编:小OO
文档
前面我们分析了Spring AOP实现中得到Proxy对象的过程,下面我们看看在Spring AOP中链是怎样被调用的,也就是Proxy模式是怎样起作用的,或者说Spring是怎样为我们提供AOP功能的; 

在JdkDynamicAopProxy中生成Proxy对象的时候: 

 

Java代码 

1.return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);  

        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

这里的this参数对应的是InvocationHandler对象,这里我们的JdkDynamicAopProxy实现了这个接口,也就是说当Proxy对象的函数被调用的时候,这个InvocationHandler的invoke方法会被作为回调函数调用,下面我们看看这个方法的实现: 

 

Java代码 

1.public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   

2.    MethodInvocation invocation = null;   

3.    Object oldProxy = null;   

4.    boolean setProxyContext = false;   

5.  

6.    TargetSource targetSource = this.advised.targetSource;   

7.    Class targetClass = null;   

8.    Object target = null;   

9.  

10.    try {   

11.        // Try special rules for equals() method and implementation of the   

12.        // Advised AOP configuration interface.   

13.  

14.        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {   

15.            // What if equals throws exception!?   

16.            // This class implements the equals(Object) method itself.   

17.            return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;   

18.        }   

19.        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {   

20.            // This class implements the hashCode() method itself.   

21.            return new Integer(hashCode());   

22.        }   

23.        if (Advised.class == method.getDeclaringClass()) {   

24.            // service invocations on ProxyConfig with the proxy config   

25.            return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);   

26.        }   

27.  

28.        Object retVal = null;   

29.  

30.        if (this.advised.exposeProxy) {   

31.            // make invocation available if necessary   

32.            oldProxy = AopContext.setCurrentProxy(proxy);   

33.            setProxyContext = true;   

34.        }   

35.  

36.        // May be null. Get as late as possible to minimize the time we "own" the target,   

37.        // in case it comes from a pool.   

38.        // 这里是得到目标对象的地方,当然这个目标对象可能来自于一个实例池或者是一个简单的JAVA对象   

39.        target = targetSource.getTarget();   

40.        if (target != null) {   

41.            targetClass = target.getClass();   

42.        }   

43.  

44.        // get the interception chain for this method   

45.        // 这里获得定义好的链   

46.        List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(   

47.                this.advised, proxy, method, targetClass);   

48.  

49.        // Check whether we have any advice. If we don't, we can fallback on direct   

50.        // reflective invocation of the target, and avoid creating a MethodInvocation.   

51.        // 如果没有设定,那么我们就直接调用目标的对应方法   

52.        if (chain.isEmpty()) {   

53.            // We can skip creating a MethodInvocation: just invoke the target directly   

54.            // Note that the final invoker must be an InvokerInterceptor so we know it does   

55.            // nothing but a reflective operation on the target, and no hot swapping or fancy proxying   

56.            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);   

57.        }   

58.        else {   

59.            // We need to create a method invocation…   

60.            // invocation = advised.getMethodInvocationFactory().getMethodInvocation(   

61.            //         proxy, method, targetClass, target, args, chain, advised);   

62.            // 如果有的设定,那么需要调用之后才调用目标对象的相应方法   

63.            // 这里通过构造一个ReflectiveMethodInvocation来实现,下面我们会看这个ReflectiveMethodInvocation类   

.            invocation = new ReflectiveMethodInvocation(   

65.                    proxy, target, method, args, targetClass, chain);   

66.  

67.            // proceed to the joinpoint through the interceptor chain   

68.            // 这里通过ReflectiveMethodInvocation来调用链和相应的目标方法   

69.            retVal = invocation.proceed();   

70.        }   

71.  

72.        // massage return value if necessary   

73.        if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {   

74.            // Special case: it returned "this" and the return type of the method is type-compatible   

75.            // Note that we can't help if the target sets   

76.            // a reference to itself in another returned object.   

77.            retVal = proxy;   

78.        }   

79.        return retVal;   

80.    }   

81.    finally {   

82.        if (target != null && !targetSource.isStatic()) {   

83.            // must have come from TargetSource   

84.            targetSource.releaseTarget(target);   

85.        }   

86.  

87.        if (setProxyContext) {   

88.            // restore old proxy   

.            AopContext.setCurrentProxy(oldProxy);   

90.        }   

91.    }   

92.}  

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        MethodInvocation invocation = null;

        Object oldProxy = null;

        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;

        Class targetClass = null;

        Object target = null;

        try {

            // Try special rules for equals() method and implementation of the

            // Advised AOP configuration interface.

            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {

                // What if equals throws exception!?

                // This class implements the equals(Object) method itself.

                return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;

            }

            if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {

                // This class implements the hashCode() method itself.

                return new Integer(hashCode());

            }

            if (Advised.class == method.getDeclaringClass()) {

                // service invocations on ProxyConfig with the proxy config

                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);

            }

            Object retVal = null;

            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.

            // 这里是得到目标对象的地方,当然这个目标对象可能来自于一个实例池或者是一个简单的JAVA对象

            target = targetSource.getTarget();

            if (target != null) {

                targetClass = target.getClass();

            }

            // get the interception chain for this method

            // 这里获得定义好的链

            List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(

                    this.advised, proxy, 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

                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);

            }

            else {

                // We need to create a method invocation...

                // invocation = advised.getMethodInvocationFactory().getMethodInvocation(

                //         proxy, method, targetClass, target, args, chain, advised);

                // 如果有的设定,那么需要调用之后才调用目标对象的相应方法

                // 这里通过构造一个ReflectiveMethodInvocation来实现,下面我们会看这个ReflectiveMethodInvocation类

                invocation = new ReflectiveMethodInvocation(

                        proxy, target, method, args, targetClass, chain);

                // proceed to the joinpoint through the interceptor chain

                // 这里通过ReflectiveMethodInvocation来调用链和相应的目标方法

                retVal = invocation.proceed();

            }

            // massage return value if necessary

            if (retVal != null && retVal == target && method.getReturnType().isInstance(proxy)) {

                // 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;

            }

            return retVal;

        }

        finally {

            if (target != null && !targetSource.isStatic()) {

                // must have come from TargetSource

                targetSource.releaseTarget(target);

            }

            if (setProxyContext) {

                // restore old proxy

                AopContext.setCurrentProxy(oldProxy);

            }

        }

    }

我们先看看目标对象方法的调用,这里是通过AopUtils的方法调用 – 使用反射机制来对目标对象的方法进行调用: 

 

Java代码 

1.public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)   

2.    throws Throwable {   

3.  

4.    // Use reflection to invoke the method.   

5.    // 利用放射机制得到相应的方法,并且调用invoke   

6.    try {   

7.        if (!Modifier.isPublic(method.getModifiers()) ||   

8.                !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {   

9.            method.setAccessible(true);   

10.        }   

11.        return method.invoke(target, args);   

12.    }   

13.    catch (InvocationTargetException ex) {   

14.        // Invoked method threw a checked exception.   

15.        // We must rethrow it. The client won't see the interceptor.   

16.        throw ex.getTargetException();   

17.    }   

18.    catch (IllegalArgumentException ex) {   

19.        throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +   

20.                method + "] on target [" + target + "]", ex);   

21.    }   

22.    catch (IllegalAccessException ex) {   

23.        throw new AopInvocationException("Couldn't access method: " + method, ex);   

24.    }   

25.}  

    public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)

        throws Throwable {

        // Use reflection to invoke the method.

        // 利用放射机制得到相应的方法,并且调用invoke

        try {

            if (!Modifier.isPublic(method.getModifiers()) ||

                    !Modifier.isPublic(method.getDeclaringClass().getModifiers())) {

                method.setAccessible(true);

            }

            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("Couldn't access method: " + method, ex);

        }

    }

对链的调用处理是在ReflectiveMethodInvocation里实现的: 

 

Java代码 

1.public Object proceed() throws Throwable {   

2.    //    We start with an index of -1 and increment early.   

3.    // 这里直接调用目标对象的方法,没有的调用或者已经调用完了,这个currentInterceptorIndex的初始值是0   

4.    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) {   

5.        return invokeJoinpoint();   

6.    }   

7.  

8.    Object interceptorOrInterceptionAdvice =   

9.        this.interceptorsAndDynamicMethodMatchers.get(this.currentInterceptorIndex);   

10.    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {   

11.        // Evaluate dynamic method matcher here: static part will already have   

12.        // been evaluated and found to match.   

13.        // 这里获得相应的,如果可以匹配的上的话,那就调用的invoke方法   

14.        InterceptorAndDynamicMethodMatcher dm =   

15.            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;   

16.        if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {   

17.            return dm.interceptor.invoke(nextInvocation());   

18.        }   

19.        else {   

20.            // Dynamic matching failed.   

21.            // Skip this interceptor and invoke the next in the chain.   

22.            // 如果匹配不上,那就调用下一个,这个时候链的位置指示后移并迭代调用当前的proceed方法   

23.            this.currentInterceptorIndex++;   

24.            return proceed();   

25.        }   

26.    }   

27.    else {   

28.        // It's an interceptor, so we just invoke it: The pointcut will have   

29.        // been evaluated statically before this object was constructed.   

30.        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(nextInvocation());   

31.    }   

32.}  

    public Object proceed() throws Throwable {

        //    We start with an index of -1 and increment early.

        // 这里直接调用目标对象的方法,没有的调用或者已经调用完了,这个currentInterceptorIndex的初始值是0

        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size()) {

            return invokeJoinpoint();

        }

        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.

            // 这里获得相应的,如果可以匹配的上的话,那就调用的invoke方法

            InterceptorAndDynamicMethodMatcher dm =

                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;

            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {

                return dm.interceptor.invoke(nextInvocation());

            }

            else {

                // Dynamic matching failed.

                // Skip this interceptor and invoke the next in the chain.

                // 如果匹配不上,那就调用下一个,这个时候链的位置指示后移并迭代调用当前的proceed方法

                this.currentInterceptorIndex++;

                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(nextInvocation());

        }

    }

这里把当前的链以及在链的位置标志都clone到一个MethodInvocation对象了,作用是当前的执行完之后,会继续沿着得到这个链执行下面的拦截行为,也就是会迭代的调用上面这个proceed: 

 

Java代码 

1.private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException {   

2.    ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone();   

3.    invocation.currentInterceptorIndex = this.currentInterceptorIndex + 1;   

4.    invocation.parent = this;   

5.    return invocation;   

6.}  

    private ReflectiveMethodInvocation nextInvocation() throws CloneNotSupportedException {

        ReflectiveMethodInvocation invocation = (ReflectiveMethodInvocation) clone();

        invocation.currentInterceptorIndex = this.currentInterceptorIndex + 1;

        invocation.parent = this;

        return invocation;

    }

这里的nextInvocation就已经包含了当前的拦截链的基本信息,我们看到在Interceptor中的实现比如TransactionInterceptor的实现中: 

 

Java代码 

1.public Object invoke(final MethodInvocation invocation) throws Throwable {   

2.   ……//这里是TransactionInterceptor插入的事务处理代码,我们会在后面分析事务处理实现的时候进行分析   

3.        try {   

4.            //这里是对配置的链进行迭代处理的调用   

5.            retVal = invocation.proceed();   

6.        }   

7.   ……//省略了和事务处理的异常处理代码 ,也是TransactionInterceptor插入的处理   

8.      else {   

9.        try {   

10.            Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,   

11.                    new TransactionCallback() {   

12.                        public Object doInTransaction(TransactionStatus status) {   

13.                             //这里是TransactionInterceptor插入对事务处理的代码   

14.                            TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);   

15.                            //这里是对配置的链进行迭代处理的调用,接着顺着进行处理   

16.                            try {                           

17.                                return invocation.proceed();   

18.                            }   

19.   ……//省略了和事务处理的异常处理代码 ,也是TransactionInterceptor插入的处理   

20.   }  

    public Object invoke(final MethodInvocation invocation) throws Throwable {

       ......//这里是TransactionInterceptor插入的事务处理代码,我们会在后面分析事务处理实现的时候进行分析

            try {

                //这里是对配置的链进行迭代处理的调用

                retVal = invocation.proceed();

            }

       ......//省略了和事务处理的异常处理代码 ,也是TransactionInterceptor插入的处理

          else {

            try {

                Object result = ((CallbackPreferringPlatformTransactionManager) getTransactionManager()).execute(txAttr,

                        new TransactionCallback() {

                            public Object doInTransaction(TransactionStatus status) {

                                 //这里是TransactionInterceptor插入对事务处理的代码

                                TransactionInfo txInfo = prepareTransactionInfo(txAttr, joinpointIdentification, status);

                                //这里是对配置的链进行迭代处理的调用,接着顺着进行处理

                                try {

                                    return invocation.proceed();

                                }

       ......//省略了和事务处理的异常处理代码 ,也是TransactionInterceptor插入的处理

       }

从上面的分析我们看到了Spring AOP的基本实现,比如Spring怎样得到Proxy,怎样利用JAVA Proxy以及反射机制对用户定义的链进行处理。下载本文

显示全文
专题