Spring AOP源码分析(拦截器调用的实现)

在Spring AOP通过JDK或者Cglib的方式生成代理对象的时候,相关的拦截器已经配置到代理对象中去了,拦截器在代理对象中的作用是通过对这些方法的回调完成的。

JdkDynamicAopProxy的invoke拦截

JdkDynamicAopProxy的invoke

@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 {
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            // If the target does not implement the equals(Object) method itself.
            return equals(args[0]);
        }
        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            // If the target does not implement the hashCode() method itself.
            return hashCode();
        }
        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;
        }

        // 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.
        // 这里是定义好的拦截器链
        List 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.
        // 如果没有定义拦截器链,那么直接调用target对应方法
        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...
            // 如果有拦截器链的设定,那么需要调用拦截器之后才调用目标对象方法
            // 通过构造一个ReflectiveMethodInovation来实现
            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.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);
        }
    }
} 
  

可以看到在执行拦截器链是递归前进的:

ReflectiveMethodInvocation的proceed

@Override
public Object proceed() throws Throwable {
    //  We start with an index of -1 and increment early.
    // 从索引为-1的拦截器开始调用,并按序递增
    // 如果拦截器链中的拦截器迭代调用完毕,这里开始调用target函数,通过反射
    // AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }

    // 这里沿着定义好的 interceptorOrInterceptionAdvice链进行处理
    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.
        // 这里对拦截器链进行匹配,如果和定义的PointCut匹配,这个Advice会得到执行
        InterceptorAndDynamicMethodMatcher dm =
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
            return dm.interceptor.invoke(this);
        }
        else {
            // Dynamic matching failed.
            // Skip this interceptor and invoke the next in the chain.
            // 如果不匹配,那么proceed递归调用,知道所有的拦截器都被运行过为止
            return proceed();
        }
    }
    else {
        // It's an interceptor, so we just invoke it: The pointcut will have
        // been evaluated statically before this object was constructed.
        // 如果是一个interceptor,直接调用这个interceptor对应的方法
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

Cglib2AopProxy的拦截

DynamicAdvisedInteceptor的intercept:

private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

    private final AdvisedSupport advised;

    public DynamicAdvisedInterceptor(AdvisedSupport advised) {
        this.advised = advised;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        Class targetClass = null;
        Object target = null;
        try {
            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 = getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }
            // 从advised中取得配置好的通知
            List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            Object retVal;
            // Check whether we only have one InvokerInterceptor: that is,
            // no real advice, but just reflective invocation of the target.
            // 如果没有AOP通知配置,那么直接调用target对象的调用方法
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                // 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 = methodProxy.invoke(target, argsToUse);
            }
            else {
                // We need to create a method invocation...
                // 通过CglibMethodInvocation来启动通知
                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
            }
            retVal = processReturnType(proxy, target, method, retVal);
            return retVal;
        }
        finally {
            if (target != null) {
                releaseTarget(target);
            }
            if (setProxyContext) {
                // Restore old proxy.
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }

    @Override
    public boolean equals(Object other) {
        return (this == other ||
                (other instanceof DynamicAdvisedInterceptor &&
                        this.advised.equals(((DynamicAdvisedInterceptor) other).advised)));
    }

    /**
     * CGLIB uses this to drive proxy creation.
     */
    @Override
    public int hashCode() {
        return this.advised.hashCode();
    }

    protected Object getTarget() throws Exception {
        return this.advised.getTargetSource().getTarget();
    }

    protected void releaseTarget(Object target) throws Exception {
        this.advised.getTargetSource().releaseTarget(target);
    }
} 
  

目标方法的调用

如果没有实现拦截器链(链为空),那么直接调用目标方法:
JdkDynamicAopProxy是通过反射实现的:
AopUtils的invokeJoinpointUsingReflection

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) {
        // 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);
    }
}

Cglib2AopProxy:

retVal = methodProxy.invoke(target, argsToUse);

Aop拦截器链的调用

两种代理拦截器链的调用都是ReflectionMethodInvocation的proceed方法。
在proceed方法中,会逐个运行拦截器的拦截方法。
在运行拦截器的拦截方法之前,需要对代理方法加一个匹配判断,通过这个匹配判断来决定拦截器是否满足切面增强的要求。
这里是PointCut中进行matches的匹配过程(见上面的proceed分析)

配置通知器(获取拦截器链)

获取拦截器链是在DynamicAdvisedInterceptor的intercept中,是通过AdvisedSupport的getInterceptsAndDynamicInterceptionAdvice获取的。
在取得拦截器链的同时,为提高取得拦截器链的效率,还为这个拦截器链设置的缓存:

AdvisedSupport#getInterceptsAndDynamicInterceptionAdvice

public class AdvisedSupport extends ProxyConfig implements Advised {

    public List getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) {
        // 这里使用cache,利用cache获取已有的inteceptor链,但是第一次还是需要自己动手生成。
        // 这个inteceptor链的生成是由 advisorChainFactory完成的
        // 这里使用的是DefaultAdvisorChainFactory
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                    this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }
} 
  

DefaultAdvisorChainFactory#intecept

@Override
// 得到注册器GlobalAdvisorAdapterRegistry,这是单例模式
public List getInterceptorsAndDynamicInterceptionAdvice(
        Advised config, Method method, Class targetClass) {

    // This is somewhat tricky... We have to process introductions first,
    // but we need to preserve order in the ultimate list.
    // 根据通知器的个数初始化一个List,xml中对ProxyFactoryBean做的inteceptNames属性的配置
    // advisor链已经在config中持有了,可以直接使用
    List interceptorList = new ArrayList(config.getAdvisors().length);
    Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
    // registry 用于实现拦截器的注册,用它对从ProxyFactoryBean配置中得到的通知器进行适配,从而获取相应的拦截器,再把它加入到前面配置好的List中
    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

    for (Advisor advisor : config.getAdvisors()) {
        if (advisor instanceof PointcutAdvisor) {
            // Add it conditionally.
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
            if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            // 拦截器链是通过AdvisorAdapterRegistory加入的,对advice的织入起到很大作用
            // 从GlobalAdvisorAdapterRegistry取得MethodInterceptor实现
                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.
                        // 在getInterceptors方法中创建新的对象实例
                        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;
}

// 判断Advisors是否符合实际要求
private static boolean hasMatchingIntroductions(Advised config, Class actualClass) {
    for (int i = 0; i < config.getAdvisors().length; i++) {
        Advisor advisor = config.getAdvisors()[i];
        if (advisor instanceof IntroductionAdvisor) {
            IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
            if (ia.getClassFilter().matches(actualClass)) {
                return true;
            }
        }
    }
    return false;
} 
  

在拦截器适配和注册过程完成后,List中的拦截器会被JDK生成的AopProxy代理对象的invoke方法或者CGLIB代理对象的intecept方法拦截,并启动拦截器的invoke调用,最终触发通知的切面增强。

在拦截器链的初始化中获取advisor通知器

ProxyFactoryBean#initializeAdvisorChain:

private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
    if (this.advisorChainInitialized) {
        return;
    }

    if (!ObjectUtils.isEmpty(this.interceptorNames)) {
        if (this.beanFactory == null) {
            throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
                    "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
        }

        // Globals can't be last unless we specified a targetSource using the property...
        if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
                this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
            throw new AopConfigException("Target required after globals");
        }

        // Materialize interceptor chain from bean names.
        for (String name : this.interceptorNames) {
            if (logger.isTraceEnabled()) {
                logger.trace("Configuring advisor or advice '" + name + "'");
            }

            if (name.endsWith(GLOBAL_SUFFIX)) {
                if (!(this.beanFactory instanceof ListableBeanFactory)) {
                    throw new AopConfigException(
                            "Can only use global advisors or interceptors with a ListableBeanFactory");
                }
                addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                        name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
            }

            else {
                // If we get here, we need to add a named interceptor.
                // We must check if it's a singleton or prototype.
                Object advice;
                // 判断Bean类型是singleTon还是protoType
                if (this.singleton || this.beanFactory.isSingleton(name)) {
                    // Add the real Advisor/Advice to the chain.
                    // 这里取得advisor的地方,是通过BeanFactory获得的
                    // 把interceptNames这个List中的interceptor名字交给BeanFactory,然后通过BeanFactory的getBean获取
                    advice = this.beanFactory.getBean(name);
                }
                else {
                    // It's a prototype Advice or Advisor: replace with a prototype.
                    // Avoid unnecessary creation of prototype bean just for advisor chain initialization.
                    // 如果bean类型是Prototype
                    advice = new PrototypePlaceholderAdvisor(name);
                }
                addAdvisorOnChainCreation(advice, name);
            }
        }
    }

    this.advisorChainInitialized = true;
}

ProxyFactoryBean需要实现BeanFactoryAware接口,然后才能把BeanFactory设置进去,ProxyFactoryBean才能获取IOC容器(一般是DefaultListableBeanFactory)。
注意ProxyFactoryBean是一个Bean,也需要配置的。

public class ProxyFactoryBean extends ProxyCreatorSupport
        implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware

这样,ProxyFactoryBean就能根据IOC容器的getBean获取在Bean定义文件中的通知器了。

IOC容器对ProxyFactoryBean依赖注入时,会将ProxyFactoryBean给出的通知器名字直接注入到FactoryBean的interceptorNames属性中。

Advice通知的实现

由GlobalAdvisorAdapterRegistory完成拦截器的适配和注册过程:
DefaultAdvisorChainFactory见上文

registry 其实是一个 DefaultAdvisorAdapterRegistry单件,DefaultAdvisorAdapterRegistory中有许多适配器,为Spring AOP advice提供编织能力:

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
    // 这个List是对应advice功能的
    private final List adapters = new ArrayList(3);


    /**
     * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
     */

    public DefaultAdvisorAdapterRegistry() {
        // 已有的advice实现功能加进来,before,afterReturn,throw
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }


    @Override
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        if (adviceObject instanceof Advisor) {
            return (Advisor) adviceObject;
        }
        if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        }
        Advice advice = (Advice) adviceObject;
        if (advice instanceof MethodInterceptor) {
            // So well-known it doesn't even need an adapter.
            return new DefaultPointcutAdvisor(advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            // Check that it is supported.
            if (adapter.supportsAdvice(advice)) {
                return new DefaultPointcutAdvisor(advice);
            }
        }
        throw new UnknownAdviceTypeException(advice);
    }

    // DefaultAdvisorChainFactory中启动的getinterceptors方法
    @Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List interceptors = new ArrayList(3);
        //从advisor通知器配置中取得advice通知
        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()]);
    }

    @Override
    public void registerAdvisorAdapter(AdvisorAdapter adapter) {
        this.adapters.add(adapter);
    }

}

这里用到适配器模式,比如MethodBeforeAdviceAdapter:

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

    @Override
    public boolean supportsAdvice(Advice advice) {
        return (advice instanceof MethodBeforeAdvice);
    }

    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }

}

MethodBeforeAdviceInterceptor实现:

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

    private MethodBeforeAdvice advice;

    // 为指定的Advice创建对应的MethodBeforeAdvice
    /**
     * Create a new MethodBeforeAdviceInterceptor for the given advice.
     * @param advice the MethodBeforeAdvice to wrap
     */
    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    @Override
    //会在代理对象的方法被调用时回调
    public Object invoke(MethodInvocation mi) throws Throwable {
        //先执行advice的before方法,在方法调用之前完成通知增强
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
        return mi.proceed();
    }

}

类似的,看AfterReturningAdviceInterceptor:

@SuppressWarnings("serial")
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

    private final AfterReturningAdvice advice;


    /**
     * Create a new AfterReturningAdviceInterceptor for the given advice.
     * @param advice the AfterReturningAdvice to wrap
     */
    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        Object retVal = mi.proceed();
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }

}

ThrowsAdviceInterceptor:

public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {

    private static final String AFTER_THROWING = "afterThrowing";

    private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class);


    private final Object throwsAdvice;

    /** Methods on throws advice, keyed by exception class */
    private final Map, Method> exceptionHandlerMap = new HashMap, Method>();


    /**
     * Create a new ThrowsAdviceInterceptor for the given ThrowsAdvice.
     * @param throwsAdvice the advice object that defines the exception
     * handler methods (usually a {@link org.springframework.aop.ThrowsAdvice}
     * implementation)
     */
    public ThrowsAdviceInterceptor(Object throwsAdvice) {
        Assert.notNull(throwsAdvice, "Advice must not be null");
        this.throwsAdvice = throwsAdvice;

        Method[] methods = throwsAdvice.getClass().getMethods();
        for (Method method : methods) {
            if (method.getName().equals(AFTER_THROWING) &&
                    (method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) &&
                    Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])
                ) {
                // Have an exception handler
                this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method);
                if (logger.isDebugEnabled()) {
                    logger.debug("Found exception handler method: " + method);
                }
            }
        }

        if (this.exceptionHandlerMap.isEmpty()) {
            throw new IllegalArgumentException(
                    "At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
        }
    }

    public int getHandlerMethodCount() {
        return this.exceptionHandlerMap.size();
    }

    /**
     * Determine the exception handle method. Can return null if not found.
     * @param exception the exception thrown
     * @return a handler for the given exception type
     */
    private Method getExceptionHandler(Throwable exception) {
        Class exceptionClass = exception.getClass();
        if (logger.isTraceEnabled()) {
            logger.trace("Trying to find handler for exception of type [" + exceptionClass.getName() + "]");
        }
        Method handler = this.exceptionHandlerMap.get(exceptionClass);
        while (handler == null && exceptionClass != Throwable.class) {
            exceptionClass = exceptionClass.getSuperclass();
            handler = this.exceptionHandlerMap.get(exceptionClass);
        }
        if (handler != null && logger.isDebugEnabled()) {
            logger.debug("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler);
        }
        return handler;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        catch (Throwable ex) {
            Method handlerMethod = getExceptionHandler(ex);
            if (handlerMethod != null) {
                invokeHandlerMethod(mi, ex, handlerMethod);
            }
            throw ex;
        }
    }

    private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
        Object[] handlerArgs;
        if (method.getParameterTypes().length == 1) {
            handlerArgs = new Object[] { ex };
        }
        else {
            handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
        }
        try {
            method.invoke(this.throwsAdvice, handlerArgs);
        }
        catch (InvocationTargetException targetEx) {
            throw targetEx.getTargetException();
        }
    }

}

ProxyFactory实现AOP

在ProxyFactory使用中,需要编程式完成AOP应用的配置。
ProxyFactory没有使用FactoryBean的IOC封装,而是直接继承ProxyCreatorSupport功能来完成AOP属性配置。
ProxyFactory也是以getProxy为入口的:

public class ProxyFactory extends ProxyCreatorSupport {

    /**
     * Create a new ProxyFactory.
     */
    public ProxyFactory() {
    }

    /**
     * Create a new ProxyFactory.
     * 

Will proxy all interfaces that the given target implements. * @param target the target object to be proxied */ public ProxyFactory(Object target) { setTarget(target); setInterfaces(ClassUtils.getAllInterfaces(target)); } /** * Create a new ProxyFactory. *

No target, only interfaces. Must add interceptors. * @param proxyInterfaces the interfaces that the proxy should implement */ public ProxyFactory(Class... proxyInterfaces) { setInterfaces(proxyInterfaces); } /** * Create a new ProxyFactory for the given interface and interceptor. *

Convenience method for creating a proxy for a single interceptor, * assuming that the interceptor handles all calls itself rather than * delegating to a target, like in the case of remoting proxies. * @param proxyInterface the interface that the proxy should implement * @param interceptor the interceptor that the proxy should invoke */ public ProxyFactory(Class proxyInterface, Interceptor interceptor) { addInterface(proxyInterface); addAdvice(interceptor); } /** * Create a ProxyFactory for the specified {@code TargetSource}, * making the proxy implement the specified interface. * @param proxyInterface the interface that the proxy should implement * @param targetSource the TargetSource that the proxy should invoke */ public ProxyFactory(Class proxyInterface, TargetSource targetSource) { addInterface(proxyInterface); setTargetSource(targetSource); } /** * Create a new proxy according to the settings in this factory. *

Can be called repeatedly. Effect will vary if we've added * or removed interfaces. Can add and remove interceptors. *

Uses a default class loader: Usually, the thread context class loader * (if necessary for proxy creation). * @return the proxy object */ public Object getProxy() { return createAopProxy().getProxy(); } /** * Create a new proxy according to the settings in this factory. *

Can be called repeatedly. Effect will vary if we've added * or removed interfaces. Can add and remove interceptors. *

Uses the given class loader (if necessary for proxy creation). * @param classLoader the class loader to create the proxy with * (or {@code null} for the low-level proxy facility's default) * @return the proxy object */ public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } /** * Create a new proxy for the given interface and interceptor. *

Convenience method for creating a proxy for a single interceptor, * assuming that the interceptor handles all calls itself rather than * delegating to a target, like in the case of remoting proxies. * @param proxyInterface the interface that the proxy should implement * @param interceptor the interceptor that the proxy should invoke * @return the proxy object * @see #ProxyFactory(Class, org.aopalliance.intercept.Interceptor) */ @SuppressWarnings("unchecked") public static T getProxy(Class proxyInterface, Interceptor interceptor) { return (T) new ProxyFactory(proxyInterface, interceptor).getProxy(); } /** * Create a proxy for the specified {@code TargetSource}, * implementing the specified interface. * @param proxyInterface the interface that the proxy should implement * @param targetSource the TargetSource that the proxy should invoke * @return the proxy object * @see #ProxyFactory(Class, org.springframework.aop.TargetSource) */ @SuppressWarnings("unchecked") public static T getProxy(Class proxyInterface, TargetSource targetSource) { return (T) new ProxyFactory(proxyInterface, targetSource).getProxy(); } /** * Create a proxy for the specified {@code TargetSource} that extends * the target class of the {@code TargetSource}. * @param targetSource the TargetSource that the proxy should invoke * @return the proxy object */ public static Object getProxy(TargetSource targetSource) { if (targetSource.getTargetClass() == null) { throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class"); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTargetSource(targetSource); proxyFactory.setProxyTargetClass(true); return proxyFactory.getProxy(); } }

你可能感兴趣的:(spring)