spring 源码探索 -- aop 标签解析和创建代理

aopNamespaceHandler

aop标签和相应的aop parser映射在一起。

注册 AspectJAnnotationAutoProxyCreator

AspectJAutoProxyBeanDefinitionParser parser方法实现注册。

AspectJAnnotationAutoProxyCreator的流程
AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator 是一个BeanPostProcessor实现,它注册的时机是在AbstractApplicationContextregisterBeanPostProcessors里面。这个方法会注册spring 容器所有BeanPostProcessor接口的实例。

调用postProcessBeforeInstantiation或者postProcessAfterInitialization

  1. 获取增强器 所有的增强器

在增强类的方法上查找aop注解

/**
     * Find and return the first AspectJ annotation on the given method
     * (there <i>should</i> only be one anyway...)
     */
    @SuppressWarnings("unchecked")
    protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
        Class<?>[] classesToLookFor = new Class<?>[] {
                Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
        for (Class<?> c : classesToLookFor) {
            AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
            if (foundAnnotation != null) {
                return foundAnnotation;
            }
        }
        return null;
    }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {
}

对于不同的增强处理(before,after…),创建不同的实例。
before AspectJMethodBeforeAdvice
使用了MethodBeforeAdviceInterceptor做拦截器,先调用自己的invoke方法,然后再调用真正before的方法
after AspectJAfterAdvice 不一样,直接调用invoke方法。

try {
            return mi.proceed();
        }
        finally {
            invokeAdviceMethod(getJoinPointMatch(), null, null);
        }

寻找匹配的增强器

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        }

        MethodMatcher methodMatcher = pc.getMethodMatcher();
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }

        Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        classes.add(targetClass);
        for (Class<?> clazz : classes) {
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if ((introductionAwareMethodMatcher != null &&
                        introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
                        methodMatcher.matches(method, targetClass)) {
                    return true;
                }
            }
        }

        return false;
    }

创建代理

上面的步骤找到了与当前bean匹配的增强器,specificInterceptors,下一步就要开始创建代理了。

从默认aop代理工厂DefaultAopProxyFactory中,根据不同的代理策略来创建aop代理,这里还没有创建代理bean

@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.");
            }
            if (targetClass.isInterface()) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

使用工厂模式创建aop代理

JdkDynamicAopProxy

典型的jdk 动态代理模式.

  1. 构造函数传入目标对象,这里是AdvisedSupport 实例
  2. getProxy
  3. invoke 先获取当前方法的拦截器链,使用ReflectiveMethodInvocation封装拦截器链,然后一个个调用。

invocation.proceed();方法中就是调用增强的方法和目标方法。

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 = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // Proceed to the joinpoint through the interceptor chain.
                retVal = invocation.proceed();
            }

CGLIB 代理

  • 典型实现
    Enhancer.setCallback(MethodInterceptorImpl) 在这里设置拦截器,
    Enhancer.create生成代理。
    MethodInterceptorImpl 中 proxy.invokeSuper(obj.args)

  • aop实现
    getCallbacks(Class...) 获取拦截器。

    将拦截器封装在DynamicAdvisedInterceptor中,该类的intercept方法负责处理拦截器的调用,处理的方式和jdk代理中的invoke很类似。

参考:http://www.jianshu.com/p/867991f3daa0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值