切面触发过程

Posted zhuxudong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了切面触发过程相关的知识,希望对你有一定的参考价值。

切面触发过程

  • 构建通知链
/**
 *  通知链工厂
 */
public interface AdvisorChainFactory {

    /**
     *  基于指定的 Advised 配置生成 org.aopalliance.intercept.MethodInterceptor 链
     */
    List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);
}

@SuppressWarnings("serial")
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {

    @Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, @Nullable Class<?> targetClass) {
        // Advisor 适配器注册中心
        final AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        // 获取所有配置的 Advisor
        final Advisor[] advisors = config.getAdvisors();
        final List<Object> interceptorList = new ArrayList<>(advisors.length);
        // 读取目标类型
        final Class<?> actualClass = targetClass != null ? targetClass : method.getDeclaringClass();
        Boolean hasIntroductions = null;

        for (final Advisor advisor : advisors) {
            // 1)PointcutAdvisor
            if (advisor instanceof PointcutAdvisor) {
                final PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    final MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    boolean match;
                    if (mm instanceof IntroductionAwareMethodMatcher) {
                        if (hasIntroductions == null) {
                            hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                        }
                        match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
                    }
                    else {
                        match = mm.matches(method, actualClass);
                    }
                    // 如果匹配目标方法
                    if (match) {
                        // 读取 MethodInterceptor
                        final MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                        if (mm.isRuntime()) {
                            // 如果方法匹配器是动态的,将 MethodInterceptor 和 MethodMatcher 封装后加入拦截器链
                            for (final MethodInterceptor interceptor : interceptors) {
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        }
                        else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
            // 2)IntroductionAdvisor
            else if (advisor instanceof IntroductionAdvisor) {
                final IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    final Interceptor[] interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
            // 3)其他 Advisor【无内置实现】
            else {
                final Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

    /**
     * Advisor 链匹配方法引入
     */
    private static boolean hasMatchingIntroductions(Advisor[] advisors, Class<?> actualClass) {
        for (final Advisor advisor : advisors) {
            if (advisor instanceof IntroductionAdvisor) {
                final IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (ia.getClassFilter().matches(actualClass)) {
                    return true;
                }
            }
        }
        return false;
    }
}

@SuppressWarnings("serial")
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
    /**
     *  Advisor 适配器
     */
    private final List<AdvisorAdapter> adapters = new ArrayList<>(3);

    /**
     * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
     */
    public DefaultAdvisorAdapterRegistry() {
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }


    @Override
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        // 本身就是 Advisor
        if (adviceObject instanceof Advisor) {
            return (Advisor) adviceObject;
        }
        if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        }
        final Advice advice = (Advice) adviceObject;
        if (advice instanceof MethodInterceptor) {
            // 本身是一个 MethodInterceptor
            return new DefaultPointcutAdvisor(advice);
        }
        for (final AdvisorAdapter adapter : adapters) {
            // 本身不是 MethodInterceptor && Advisor 支持此 Advice
            if (adapter.supportsAdvice(advice)) {
                return new DefaultPointcutAdvisor(advice);
            }
        }
        throw new UnknownAdviceTypeException(advice);
    }

    @Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        // 将目标 Advisor 的所有通知适配为 MethodInterceptor
        final List<MethodInterceptor> interceptors = new ArrayList<>(3);
        final Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (final AdvisorAdapter adapter : adapters) {
            // 如果目标适配器支持此 advice && 将其适配为 MethodInterceptor
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[0]);
    }

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

/**
 *  将 MethodBeforeAdvice 适配为 MethodInterceptor
 */
@SuppressWarnings("serial")
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

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

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

@SuppressWarnings("serial")
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 {
        // 执行前置通知
        advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        // 执行拦截连中的下一个拦截器
        return mi.proceed();
    }
}

/**
 *  将 AfterReturningAdvice 适配为 MethodInterceptor
 */
@SuppressWarnings("serial")
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {

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

    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        final AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
        return new AfterReturningAdviceInterceptor(advice);
    }
}

@SuppressWarnings("serial")
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
    private final AfterReturningAdvice advice;

    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        // 执行下一个拦截器
        final Object retVal = mi.proceed();
        // 执行方法返回通知
        advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
}

/**
 *  将 ThrowsAdvice 适配为 MethodInterceptor
 */
@SuppressWarnings("serial")
class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {

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

    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        return new ThrowsAdviceInterceptor(advisor.getAdvice());
    }
}

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<Class<?>, Method> exceptionHandlerMap = new HashMap<>();

    public ThrowsAdviceInterceptor(Object throwsAdvice) {
        Assert.notNull(throwsAdvice, "Advice must not be null");
        this.throwsAdvice = throwsAdvice;

        final Method[] methods = throwsAdvice.getClass().getMethods();
        for (final Method method : methods) {
            /**
             *  查找 1 个参数 public void afterThrowing(Exception ex)
             *  或 4 个参数 public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
             *  的指定格式的异常处理器
             */
            if (method.getName().equals(AFTER_THROWING) &&
                    (method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
                final Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
                if (Throwable.class.isAssignableFrom(throwableParam)) {
                    // 注册异常处理器
                    exceptionHandlerMap.put(throwableParam, method);
                    if (logger.isDebugEnabled()) {
                        logger.debug("Found exception handler method on throws advice: " + method);
                    }
                }
            }
        }

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

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

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        catch (final Throwable ex) {
            final Method handlerMethod = getExceptionHandler(ex);
            if (handlerMethod != null) {
                // 触发异常处理器
                invokeHandlerMethod(mi, ex, handlerMethod);
            }
            throw ex;
        }
    }

    @Nullable
    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 = exceptionHandlerMap.get(exceptionClass);
        while (handler == null && exceptionClass != Throwable.class) {
            exceptionClass = exceptionClass.getSuperclass();
            handler = exceptionHandlerMap.get(exceptionClass);
        }
        if (handler != null && logger.isTraceEnabled()) {
            logger.trace("Found handler for exception of type [" + exceptionClass.getName() + "]: " + handler);
        }
        return handler;
    }

    private void invokeHandlerMethod(MethodInvocation mi, Throwable ex, Method method) throws Throwable {
        Object[] handlerArgs;
        if (method.getParameterCount() == 1) {
            handlerArgs = new Object[] {ex};
        }
        else {
            handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(), mi.getThis(), ex};
        }
        try {
            method.invoke(throwsAdvice, handlerArgs);
        }
        catch (final InvocationTargetException targetEx) {
            throw targetEx.getTargetException();
        }
    }
}
  • 构建 ReflectiveMethodInvocation 触发通知链和切点方法调用
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    /**
     *  代理对象
     */
    protected final Object proxy;
    /**
     *  目标对象
     */
    @Nullable
    protected final Object target;
    /**
     *  目标方法
     */
    protected final Method method;
    /**
     *  参数数组
     */
    protected Object[] arguments = new Object[0];
    /**
     *  目标类型
     */
    @Nullable
    private final Class<?> targetClass;

    /**
     *  用户特定属性
     */
    @Nullable
    private Map<String, Object> userAttributes;
    /**
     * List of MethodInterceptor and InterceptorAndDynamicMethodMatcher
     * that need dynamic checks.
     */
    protected final List<?> interceptorsAndDynamicMethodMatchers;

    /**
     *  当前执行的目标拦截器索引
     */
    private int currentInterceptorIndex = -1;

    protected ReflectiveMethodInvocation(
            Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
            @Nullable 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;
    }

    @Override
    public final Object getProxy() {
        return proxy;
    }

    @Override
    @Nullable
    public final Object getThis() {
        return target;
    }

    @Override
    public final AccessibleObject getStaticPart() {
        return method;
    }

    @Override
    public final Method getMethod() {
        return method;
    }

    @Override
    public final Object[] getArguments() {
        return arguments;
    }

    @Override
    public void setArguments(Object... arguments) {
        this.arguments = arguments;
    }


    @Override
    @Nullable
    public Object proceed() throws Throwable {
        //  所有的拦截器都已经执行完毕,则执行目标方法
        if (currentInterceptorIndex == interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        // 获取指定索引处的拦截器
        final Object interceptorOrInterceptionAdvice =
                interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
        // 1)如果是动态匹配执行
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            final InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            final Class<?> targetClass = this.targetClass != null ? this.targetClass : method.getDeclaringClass();
            // 如果匹配,则执行当前的拦截器
            if (dm.methodMatcher.matches(method, targetClass, arguments)) {
                return dm.interceptor.invoke(this);
            }
            else {
                // 直接执行下一个拦截器
                return proceed();
            }
        }
        else {
            // 2)执行此拦截器
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }

    /**
     *  通过反射的方式执行切入点方法
     */
    @Nullable
    protected Object invokeJoinpoint() throws Throwable {
        return AopUtils.invokeJoinpointUsingReflection(target, method, arguments);
    }

    @Override
    public MethodInvocation invocableClone() {
        Object[] cloneArguments = arguments;
        if (arguments.length > 0) {
            // Build an independent copy of the arguments array.
            cloneArguments = new Object[arguments.length];
            System.arraycopy(arguments, 0, cloneArguments, 0, arguments.length);
        }
        return invocableClone(cloneArguments);
    }

    @Override
    public MethodInvocation invocableClone(Object... arguments) {
        if (userAttributes == null) {
            userAttributes = new HashMap<>();
        }

        // Create the MethodInvocation clone.
        try {
            final ReflectiveMethodInvocation clone = (ReflectiveMethodInvocation) clone();
            clone.arguments = arguments;
            return clone;
        }
        catch (final CloneNotSupportedException ex) {
            throw new IllegalStateException(
                    "Should be able to clone object of type [" + getClass() + "]: " + ex);
        }
    }

    @Override
    public void setUserAttribute(String key, @Nullable Object value) {
        if (value != null) {
            if (userAttributes == null) {
                userAttributes = new HashMap<>();
            }
            userAttributes.put(key, value);
        }
        else {
            if (userAttributes != null) {
                userAttributes.remove(key);
            }
        }
    }

    @Override
    @Nullable
    public Object getUserAttribute(String key) {
        return userAttributes != null ? userAttributes.get(key) : null;
    }

    public Map<String, Object> getUserAttributes() {
        if (userAttributes == null) {
            userAttributes = new HashMap<>();
        }
        return userAttributes;
    }


    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("ReflectiveMethodInvocation: ");
        sb.append(method).append("; ");
        if (target == null) {
            sb.append("target is null");
        }
        else {
            sb.append("target is of class [").append(target.getClass().getName()).append(‘]‘);
        }
        return sb.toString();
    }
}

@SuppressWarnings("serial")
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 {
        // 执行前置通知
        advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        // 执行拦截连中的下一个拦截器
        return mi.proceed();
    }
}

@SuppressWarnings("serial")
public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {

    public AspectJAroundAdvice(
            Method aspectJAroundAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
        super(aspectJAroundAdviceMethod, pointcut, aif);
    }

    @Override
    public boolean isBeforeAdvice() {
        return false;
    }

    @Override
    public boolean isAfterAdvice() {
        return false;
    }

    @Override
    protected boolean supportsProceedingJoinPoint() {
        return true;
    }

    /**
     *  执行目标方法
     */
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        if (!(mi instanceof ProxyMethodInvocation)) {
            throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
        }
        final ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
        final ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
        final JoinPointMatch jpm = getJoinPointMatch(pmi);
        return invokeAdviceMethod(pjp, jpm, null, null);
    }

    /**
     * Return the ProceedingJoinPoint for the current invocation,
     */
    protected ProceedingJoinPoint lazyGetProceedingJoinPoint(ProxyMethodInvocation rmi) {
        return new MethodInvocationProceedingJoinPoint(rmi);
    }

}

@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;
    }

}

@SuppressWarnings("serial")
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {

    public AspectJAfterThrowingAdvice(
            Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
        super(aspectJBeforeAdviceMethod, pointcut, aif);
    }

    @Override
    public boolean isBeforeAdvice() {
        return false;
    }

    @Override
    public boolean isAfterAdvice() {
        return true;
    }

    @Override
    public void setThrowingName(String name) {
        setThrowingNameNoCheck(name);
    }

    /**
     *  执行目标方法
     */
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        catch (final Throwable ex) {
            // 是否需要执行异常通知
            if (shouldInvokeOnThrowing(ex)) {
                invokeAdviceMethod(getJoinPointMatch(), null, ex);
            }
            throw ex;
        }
    }

    /**
     *  异常类型是否和通知方法中的参数匹配
     */
    private boolean shouldInvokeOnThrowing(Throwable ex) {
        return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
    }
}

@SuppressWarnings("serial")
public class AspectJAfterAdvice extends AbstractAspectJAdvice
implements MethodInterceptor, AfterAdvice, Serializable {

    public AspectJAfterAdvice(
            Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {
        super(aspectJBeforeAdviceMethod, pointcut, aif);
    }

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            // 执行目标方法
            return mi.proceed();
        }
        finally {
            invokeAdviceMethod(getJoinPointMatch(), null, null);
        }
    }

    @Override
    public boolean isBeforeAdvice() {
        return false;
    }

    @Override
    public boolean isAfterAdvice() {
        return true;
    }
}

以上是关于切面触发过程的主要内容,如果未能解决你的问题,请参考以下文章

MySql触发器使用

MySQL触发器

片段创建的 Intent 不会触发 onNewIntent

导航到另一个片段时触发 API 调用

阿里四面:你知道Spring AOP创建Proxy的过程吗?

使用触发器对学生表操作进行日志记录