Aop源码分析

先来个简单demo 

1首先在xml配置使用aop的标签

2.在创建一个切面系统

3.然后进行测试就行了 666666666666666

源码分析:首先aop 是自定义标签,我们知道spring解析自定义标签的步骤会

首先获取标签的命名空间,

然后提取自定义的解析器,

最后进行自定义标签的解析

其中得到名称空间会马上执行继承了 NamespaceHandlerSupport 中的init()方法进行解析器的注册
 

 NamespaceHandler namespaceHandler = (NamespaceHandler)BeanUtils.instantiateClass(handlerClass);
                    namespaceHandler.init();
                    handlerMappings.put(namespaceUri, namespaceHandler);
                    return namespaceHandler;

解析返回的是一个BeanDedinition,parse()方法的实现在NamespaceHandlerSupport

	private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
//localName 为aop
		String localName = parserContext.getDelegate().getLocalName(element);
//找到aop 对应的解析器 AspectJAutoProxyBeanDefinitionParser
		BeanDefinitionParser parser = this.parsers.get(localName);
		if (parser == null) {
			parserContext.getReaderContext().fatal(
					"Cannot locate BeanDefinitionParse
r for element [" + localName + "]", element);
		}
		return parser;

所有的解析器都是对BeanDefinitionParser接口的统一实现:

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser

入口都为parse()方法


    public BeanDefinition parse(Element element, ParserContext parserContext) {
        AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
        this.extendBeanDefinition(element, parserContext);
        return null;

  public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
        BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
        useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
        registerComponentIfNecessary(beanDefinition, parserContext);
    }
 public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
        return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    }

 

 主要是向容器中注册了AnnotationAwareAspectJAutoProxyCreator;类型的组件

AnnotationAwareAspectJAutoProxyCreator 的父类AbstractAutoProxyCreator 实现BeanPostProcess

   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if(!this.earlyProxyReferences.contains(cacheKey)) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }




protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if(beanName != null && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if(!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
//获取增强器
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if(specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);

//创建代理对象
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }

获取增强器其实是有AnnotationAwareAspectJAutoProxyCreator中的:

protected List<Advisor> findCandidateAdvisors() {
        List<Advisor> advisors = super.findCandidateAdvisors();
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        return advisors;
    }

这个时候返回的增强器有两个一个是after增强器,另一个为before增强器

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
    this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//切点信息的获取 :也就是execution 表达式
    AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
//红色标记   使用切点信息生成增强器
    return expressionPointcut == null?null:new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

 

//获取方法上面的注解
 protected static AbstractAspectJAdvisorFactory.AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
        Class<?>[] classesToLookFor = new Class[]{Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
        Class[] var2 = classesToLookFor;
        int var3 = classesToLookFor.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            Class<?> c = var2[var4];
            AbstractAspectJAdvisorFactory.AspectJAnnotation<?> foundAnnotation = findAnnotation(method, c);
            if(foundAnnotation != null) {
                return foundAnnotation;
            }
        }

        return null;
    }

 这里使用了后置增强

 

JdkDynamicAopProxy 的

 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        TargetSource targetSource = this.advised.targetSource;
        Class<?> targetClass = null;
        Object target = null;

        Boolean var10;
        try {
            if(this.equalsDefined || !AopUtils.isEqualsMethod(method)) {
                if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                    Integer var20 = Integer.valueOf(this.hashCode());
                    return var20;
                }

                if(method.getDeclaringClass() == DecoratingProxy.class) {
                    Class var18 = AopProxyUtils.ultimateTargetClass(this.advised);
                    return var18;
                }

                Object retVal;
                if(!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                    retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
                    return retVal;
                }

                if(this.advised.exposeProxy) {
                    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 {
                    MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                    retVal = invocation.proceed();
                }

                Class<?> returnType = method.getReturnType();
                if(retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                    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);
                }

                Object var13 = retVal;
                return var13;
            }

            var10 = Boolean.valueOf(this.equals(args[0]));
        } finally {
            if(target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }

            if(setProxyContext) {
                AopContext.setCurrentProxy(oldProxy);
            }

        }

        return var10;
    }
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

代理对象-----执行目标方法时候会进入intercept()方法

//获得拦截器链

拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//拦截器链为空,直接执行目标方法
if(chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
    retVal = methodProxy.invoke(target, argsToUse);
} else {
//不为空把需要执行的目标对象,目标方法,   拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
    retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
}

}

拦截器链的触发过程;
        1)、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;

 return this.invokeJoinpoint();
 return method.invoke(target, args);//执行目标方法


             2)、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
          拦截器链的机制,保证通知方法与目标方法的执行顺序;

先执行before()的通知方法

继续执行after的通知方法

注解版的

@EnableAspectJAutoProxy
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})//想容器总注册AspectJAutoProxyRegistrar注解
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值