Spring AOP 源码

Advice通知:

以MethodBeforeAdvice为例子,bean需要实现接口

public interface Advice {

}
public interface BeforeAdvice extends Advice {

}
public interface MethodBeforeAdvice extends BeforeAdvice {

    // 实现回调函数
    void before(Method method, Object[] args, Object target) throws Throwable;

}

PointCut 切点:

以JdkRegexpMethodPointcut,用于描述切面的方法

public interface Pointcut {

    ClassFilter getClassFilter();

    MethodMatcher getMethodMatcher();

    Pointcut TRUE = TruePointcut.INSTANCE;

}

实现

@SuppressWarnings("serial")
public class JdkRegexpMethodPointcut extends AbstractRegexpMethodPointcut {

    private Pattern[] compiledPatterns = new Pattern[0];

    private Pattern[] compiledExclusionPatterns = new Pattern[0];

    @Override
    protected void initPatternRepresentation(String[] patterns) throws PatternSyntaxException {
        this.compiledPatterns = compilePatterns(patterns);
    }

    @Override
    protected void initExcludedPatternRepresentation(String[] excludedPatterns) throws PatternSyntaxException {
        this.compiledExclusionPatterns = compilePatterns(excludedPatterns);
    }

    // 匹配方法名,标示是否进入切面
    @Override
    protected boolean matches(String pattern, int patternIndex) {
        Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
        return matcher.matches();
    }

    @Override
    protected boolean matchesExclusion(String candidate, int patternIndex) {
        Matcher matcher = this.compiledExclusionPatterns[patternIndex].matcher(candidate);
        return matcher.matches();
    }

    private Pattern[] compilePatterns(String[] source) throws PatternSyntaxException {
        Pattern[] destination = new Pattern[source.length];
        for (int i = 0; i < source.length; i++) {
            destination[i] = Pattern.compile(source[i]);
        }
        return destination;
    }

}

Adviser 通知器:

@SuppressWarnings("serial")
public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {

    // 切点
    private Pointcut pointcut = Pointcut.TRUE;

    public DefaultPointcutAdvisor() {
    }

    // 通知
    public DefaultPointcutAdvisor(Advice advice) {
        this(Pointcut.TRUE, advice);
    }

    public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
        this.pointcut = pointcut;
        setAdvice(advice);
    }

    public void setPointcut(Pointcut pointcut) {
        this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE);
    }

    @Override
    public Pointcut getPointcut() {
        return this.pointcut;
    }


    @Override
    public String toString() {
        return getClass().getName() + ": pointcut [" + getPointcut() + "]; advice [" + getAdvice() + "]";
    }

}

class TruePointcut implements Pointcut, Serializable {

    // 单例模式
    public static final TruePointcut INSTANCE = new TruePointcut();

    ...
}

动态代理:

aop代理工厂:

public interface AopProxyFactory {

    AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;

}

默认代理工厂实现类:
两种实现方式:jdk和cglib

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            // 如果目标类型是接口,则使用JDK动态代理,因为cglib是采用继承的方式实现动态代理的
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] ifcs = config.getProxiedInterfaces();
        return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
    }

}

动态代理invoke方法实现:

以JdkDynamicAopProxy为例

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

    ...
    @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 {
            ...

            Object retVal;

            if (this.advised.exposeProxy) {
                // Make invocation available if necessary.
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            // 得到目标对象
            target = targetSource.getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }

            // 得到拦截器链
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            if (chain.isEmpty()) {
                // 如果没有设定拦截器,直接执行
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                // 如果有拦截器,则先进行拦截器操作再进行对应方法的执行
                // 注意是拦截器列表
                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 :

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

    ...

    @Override
    public Object proceed() throws Throwable {
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm =
                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
            if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
                // 进行拦截器操作成功,执行拦截器
                return dm.interceptor.invoke(this);
            }
            else {
                // 拦截失败,进行下一个拦截器的匹配进行,直至所有拦截器都被运行过
                return proceed();
            }
        }
        else {
            // 如果是拦截器,直接获取拦截器直接执行 
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }

    ...

}

获取拦截器链:

带有缓存策略

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
        // 利用缓存储存
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List<Object> cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            // 首次生成
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                    this, method, targetClass);
            // 加入缓存
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }

DefaultAdvisorChainFactory 生成拦截器链:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass) {
        ArrayList interceptorList = new ArrayList(config.getAdvisors().length);
        Class actualClass = targetClass != null?targetClass:method.getDeclaringClass();
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        // 拦截器通过AdvisorAdapterRegistry进行注册
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        Advisor[] var8 = config.getAdvisors();
        int var9 = var8.length;

        for(int var10 = 0; var10 < var9; ++var10) {
            Advisor advisor = var8[var10];
            MethodInterceptor[] interceptors1;
            if(advisor instanceof PointcutAdvisor) {
                PointcutAdvisor var20 = (PointcutAdvisor)advisor;
                // 获取pointcut
                // 检验是否match,match后会加入list
                if(config.isPreFiltered() || var20.getPointcut().getClassFilter().matches(actualClass)) {
                    interceptors1 = registry.getInterceptors(advisor);
                    MethodMatcher mm = var20.getPointcut().getMethodMatcher();
                    if(MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if(mm.isRuntime()) {
                            MethodInterceptor[] var15 = interceptors1;
                            int var16 = interceptors1.length;

                            for(int var17 = 0; var17 < var16; ++var17) {
                                MethodInterceptor interceptor = var15[var17];
                                // 加入拦截器列表
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        } else {
                            interceptorList.addAll(Arrays.asList(interceptors1));
                        }
                    }
                }
            } else if(advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor var19 = (IntroductionAdvisor)advisor;
                if(config.isPreFiltered() || var19.getClassFilter().matches(actualClass)) {
                    interceptors1 = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors1));
                }
            } else {
                MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

Proxy:
通过JDK或者CGLIB的动态代理策略,生成AopProxy,得到拦截器链后,先遍历拦截器链然后才进行对实体指定方法的执行。而Advisor通知器也正因为拦截器链的存在才能起作用。

JDK和cglib的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值