Spring源码解析(二)AOP

超详细的Java知识点路线图


概述

本文记录下看AOP源码的过程

回顾AOP

AOP是什么

  • 面向切面编程
  • Spring的两大特性之一
  • 是OOP的重要补充

AOP有什么用

  • 代码解耦
  • 关注横向关系
  • 分离核心业务和非核心业务
  • 应用场景有:事务管理、缓存管理、日志收集、权限控制、性能监控等

AOP有哪些概念

  • Aspect(切面) 哪些方法会被切中,切中后如何处理
  • PointCut(切入点)定义哪些方法被切中,Java的AOP只支持方法,其他语言可以支持构造方法或属性
  • JoinPoint(连接点)被切中的方法
  • Advise(通知)在原有方法的基础上,加入新的功能
    • 前置 before
    • 后置 after
    • 环绕 around
    • 返回后置 afterReturning
    • 异常后置 afterThrowing
  • Weave(织入)在原有方法的功能上,加入新功能过程

AOP的实现原理

在这里插入图片描述

源码解析

解析源码需要带着目的来看,这次主要看两个重点:

  1. aop有关的标签是如何解析并注册到IOC容器中的
  2. 获得JavaBean时是如何产生动态代理的

接下来我们看看Spring源码中进行AOP的过程,首先我们要找到AOP的入口。
这不像IOC的源码有具体的类和方法可以直接进入,AOP是自动进行的,它是在哪里导入到Spring中的呢?
我们可以回想一下IOC的过程:
有一个步骤是分别解析默认的命名空间和自定义的命名空间,aop就属于自定义命名空间,会不会在这里Spring做了特殊的处理?
我们从这个位置进入看看:

DefaultBeanDefinitionDocumentReader类:

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();

        for(int i = 0; i < nl.getLength(); ++i) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element)node;
                if (delegate.isDefaultNamespace(ele)) {
//解析默认命名空间
                    this.parseDefaultElement(ele, delegate);
                } else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    } else {
  		//解析自定义命名空间
        delegate.parseCustomElement(root);
    }
}

进入解析自定义命名空间的方法,首先是拿到元素的URI,对于AOP就是http://www.springframework.org/schema/aop,然后通过URI找到对应的命名空间处理器NamespaceHandler,对应AOP的处理器就是AOPNamespaceHandler,然后由处理器来进行解析。
BeanDefinitionParserDelegate类:

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
//获得Element的URI
    String namespaceUri = this.getNamespaceURI(ele);
//通过URI找到处理器
    NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
    if (handler == null) {
        this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
        return null;
    } else {
//解析XML元素
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }
}

看下AopNamespaceHandler类

public class AopNamespaceHandler extends NamespaceHandlerSupport {
    public AopNamespaceHandler() {
    }

    public void init() {
        this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
        this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
        this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
        this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
    }
}

它实际上就是注册了四个解析器来处理四种aop标签:

  • config ConfigBeanDefinitionParser
  • aspectj-autoproxy AspectJAutoProxyBeanDefinitionParser
  • scoped-proxy ScopedProxyBeanDefinitionDecorator
  • spring-configured SpringConfiguredBeanDefinitionParser

我们最常用的是aop:config标签,接下来我们看看ConfigBeanDefinitionParser类
这个类中主要有个parse方法,第一个参数是XML元素,第二个是解析器上下文

public BeanDefinition parse(Element element, ParserContext parserContext) {
    CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
    parserContext.pushContainingComponent(compositeDef);
    this.configureAutoProxyCreator(parserContext, element);
    List<Element> childElts = DomUtils.getChildElements(element);
    Iterator var5 = childElts.iterator();

    while(var5.hasNext()) {
        Element elt = (Element)var5.next();
        String localName = parserContext.getDelegate().getLocalName(elt);
        if ("pointcut".equals(localName)) {
            this.parsePointcut(elt, parserContext);
        } else if ("advisor".equals(localName)) {
            this.parseAdvisor(elt, parserContext);
        } else if ("aspect".equals(localName)) {
            this.parseAspect(elt, parserContext);
        }
    }

    parserContext.popAndRegisterContainingComponent();
    return null;
}

下面部分通过标签名称的判断,解析config标签中的pointcut、advisor和aspect这三个标签。先看看切面部分的解析:

private void parseAspect(Element aspectElement, ParserContext parserContext) {
//获得aspect的id和name值
    String aspectId = aspectElement.getAttribute("id");
    String aspectName = aspectElement.getAttribute("ref");

    try {
        this.parseState.push(new AspectEntry(aspectId, aspectName));
        List<BeanDefinition> beanDefinitions = new ArrayList();
        List<BeanReference> beanReferences = new ArrayList();
//获得已知的父类元素
        List<Element> declareParents = DomUtils.getChildElementsByTagName(aspectElement, "declare-parents");
//解析所有的父类元素
        for(int i = 0; i < declareParents.size(); ++i) {
            Element declareParentsElement = (Element)declareParents.get(i);
            beanDefinitions.add(this.parseDeclareParents(declareParentsElement, parserContext));
        }
        NodeList nodeList = aspectElement.getChildNodes();
        boolean adviceFoundAlready = false;
//遍历所有子节点
        for(int i = 0; i < nodeList.getLength(); ++i) {
            Node node = nodeList.item(i);
//判断是否是before、after、after-returning、after-throwing、around   
if (this.isAdviceNode(node, parserContext)) {
                if (!adviceFoundAlready) {
                    adviceFoundAlready = true;
                    if (!StringUtils.hasText(aspectName)) {
                        parserContext.getReaderContext().error("<aspect> tag needs aspect bean reference via 'ref' attribute when declaring advices.", aspectElement, this.parseState.snapshot());
                        return;
                    }

                    beanReferences.add(new RuntimeBeanReference(aspectName));
                }
//解析每个advice,并添加到集合中
                AbstractBeanDefinition advisorDefinition = this.parseAdvice(aspectName, i, aspectElement, (Element)node, parserContext, beanDefinitions, beanReferences);
                beanDefinitions.add(advisorDefinition);
            }
        }

        AspectComponentDefinition aspectComponentDefinition = this.createAspectComponentDefinition(aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);
        parserContext.pushContainingComponent(aspectComponentDefinition);
        List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, "pointcut");
        Iterator var21 = pointcuts.iterator();
//解析aspect中所有的pointcut子节点
        while(var21.hasNext()) {
            Element pointcutElement = (Element)var21.next();
            this.parsePointcut(pointcutElement, parserContext);
        }

     	//发送注册完成的事件
parserContext.popAndRegisterContainingComponent();
    } finally {
        this.parseState.pop();
    }
}

在看看Advice的解析:

private AbstractBeanDefinition parseAdvice(String aspectName, int order, 
Element aspectElement, Element adviceElement, ParserContext parserContext, List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
    RootBeanDefinition var12;
    try {
//入栈一个解析状态
        this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));
//创建BeanDefinition,保存方法的信息
        RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);
        methodDefinition.getPropertyValues().add("targetBeanName", aspectName);
methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));
        methodDefinition.setSynthetic(true);
//创建BeanDefinition,保存工厂信息
        RootBeanDefinition aspectFactoryDef = new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
        aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);
        aspectFactoryDef.setSynthetic(true);
//把前面解析出来的内容包装起来,创建一个Advise方法的BeanDefinition
        AbstractBeanDefinition adviceDef = this.createAdviceDefinition(adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef, beanDefinitions, beanReferences);
//所有内容最后放在这个BeanDefinition中
        RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);
        advisorDefinition.setSource(parserContext.extractSource(adviceElement));
//将Advice的定义添加到Advisor的构造方法参数中
advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);
       //解析aspect的order属性
   if (aspectElement.hasAttribute("order")) {
            advisorDefinition.getPropertyValues().add("order", aspectElement.getAttribute("order"));
        }

        //在IOC容器中注册Advisor的BeanDefinition
parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);
        var12 = advisorDefinition;
    } finally {
        this.parseState.pop();
    }

    return var12;
}

创建Advise定义的方法,这个方法把前面解析的一系列内容放到BeanDefinition中。

private AbstractBeanDefinition createAdviceDefinition(Element adviceElement, ParserContext parserContext, String aspectName, int order, RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef, List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
//获得Advise的类型,并创建一个BeanDefinition
    RootBeanDefinition adviceDefinition = new RootBeanDefinition(this.getAdviceClass(adviceElement, parserContext));
    adviceDefinition.setSource(parserContext.extractSource(adviceElement));
    adviceDefinition.getPropertyValues().add("aspectName", aspectName);
    adviceDefinition.getPropertyValues().add("declarationOrder", order);
    if (adviceElement.hasAttribute("returning")) {
        adviceDefinition.getPropertyValues().add("returningName", adviceElement.getAttribute("returning"));
    }

    if (adviceElement.hasAttribute("throwing")) {
        adviceDefinition.getPropertyValues().add("throwingName", adviceElement.getAttribute("throwing"));
    }

    if (adviceElement.hasAttribute("arg-names")) {
        adviceDefinition.getPropertyValues().add("argumentNames", adviceElement.getAttribute("arg-names"));
    }

    ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues();
    cav.addIndexedArgumentValue(0, methodDef);
    Object pointcut = this.parsePointcutProperty(adviceElement, parserContext);
    if (pointcut instanceof BeanDefinition) {
        cav.addIndexedArgumentValue(1, pointcut);
        beanDefinitions.add((BeanDefinition)pointcut);
    } else if (pointcut instanceof String) {
        RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String)pointcut);
        cav.addIndexedArgumentValue(1, pointcutRef);
        beanReferences.add(pointcutRef);
    }

    cav.addIndexedArgumentValue(2, aspectFactoryDef);
    return adviceDefinition;
}

private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) {
    String elementName = parserContext.getDelegate().getLocalName(adviceElement);
    if ("before".equals(elementName)) {
        return AspectJMethodBeforeAdvice.class;
    } else if ("after".equals(elementName)) {
        return AspectJAfterAdvice.class;
    } else if ("after-returning".equals(elementName)) {
        return AspectJAfterReturningAdvice.class;
    } else if ("after-throwing".equals(elementName)) {
        return AspectJAfterThrowingAdvice.class;
    } else if ("around".equals(elementName)) {
        return AspectJAroundAdvice.class;
    } else {
        throw new IllegalArgumentException("Unknown advice kind [" + elementName + "].");
    }
}

到这里aop:config标签里的所有内容都被解析出来了,包装成BeanDefinition,并注册到IOC的容器中了。
再看动态代理是如何产生的,所有的Bean包括代理,都可以通过getBean来获得,我们从这条线索跟下去:
AbstractApplicationContext类:

public Object getBean(String name) throws BeansException {
    this.assertBeanFactoryActive();
    //这里
    return this.getBeanFactory().getBean(name);
}

AbstractBeanFactory类:

public Object getBean(String name) throws BeansException {
//这里
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}

跟进去

protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
    final String beanName = this.transformedBeanName(name);
    Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if (sharedInstance != null && args == null) {
        if (this.logger.isDebugEnabled()) {
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
//这里  获得JavaBean实例对象
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        ...
     }
}

跟进去

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
        throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
    } else if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
        Object object = null;
        if (mbd == null) {
            object = this.getCachedObjectForFactoryBean(beanName);
        }

        if (object == null) {
            FactoryBean<?> factory = (FactoryBean)beanInstance;
            if (mbd == null && this.containsBeanDefinition(beanName)) {
                mbd = this.getMergedLocalBeanDefinition(beanName);
            }

            boolean synthetic = mbd != null && mbd.isSynthetic();
//这里 通过工厂Bean获得对象
            object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
        }

        return object;
    } else {
        return beanInstance;
    }
}

跟进去

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
        throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
    } else if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
        Object object = null;
        if (mbd == null) {
            object = this.getCachedObjectForFactoryBean(beanName);
        }

        if (object == null) {
            FactoryBean<?> factory = (FactoryBean)beanInstance;
            if (mbd == null && this.containsBeanDefinition(beanName)) {
                mbd = this.getMergedLocalBeanDefinition(beanName);
            }

            boolean synthetic = mbd != null && mbd.isSynthetic();
//这里
            object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
        }

        return object;
    } else {
        return beanInstance;
    }
}

跟进去

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
    if (factory.isSingleton() && this.containsSingleton(beanName)) {
        synchronized(this.getSingletonMutex()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) {
       // 这里
                object = this.doGetObjectFromFactoryBean(factory, beanName);
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                } else {
                    if (object != null && shouldPostProcess) {
                        try {
                            object = this.postProcessObjectFromFactoryBean(object, beanName);
                        } catch (Throwable var9) {
                            throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var9);
                        }
                    }

                    this.factoryBeanObjectCache.put(beanName, object != null ? object : NULL_OBJECT);
                }
            }

            return object != NULL_OBJECT ? object : null;
        }
    } else {
        Object object = this.doGetObjectFromFactoryBean(factory, beanName);
        if (object != null && shouldPostProcess) {
            try {
                object = this.postProcessObjectFromFactoryBean(object, beanName);
            } catch (Throwable var11) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", var11);
            }
        }

        return object;
    }
}

跟进去

private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, String beanName) throws BeanCreationException {
    Object object;
    try {
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = this.getAccessControlContext();

            try {
                object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                    public Object run() throws Exception {
                        return factory.getObject();
                    }
                }, acc);
            } catch (PrivilegedActionException var6) {
                throw var6.getException();
            }
        } else {
//这里
            object = factory.getObject();
        }
    } catch (FactoryBeanNotInitializedException var7) {
        throw new BeanCurrentlyInCreationException(beanName, var7.toString());
    } catch (Throwable var8) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
    }

    if (object == null && this.isSingletonCurrentlyInCreation(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
    } else {
        return object;
    }
}

这个getObject就是从工厂中拿到对象了,FactoryBean有很多种实现类,我们往下跟ProxyFactoryBean也就是代理的工厂Bean。

ProxyFactoryBean

public Object getObject() throws BeansException {
    this.initializeAdvisorChain();
    if (this.isSingleton()) {
//生产单例对象
        return this.getSingletonInstance();
    } else {
        if (this.targetName == null) {
            this.logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
        }
        //创建多例对象
        return this.newPrototypeInstance();
    }
}

看看如何获得单例对象的

private synchronized Object getSingletonInstance() {
    if (this.singletonInstance == null) {
        this.targetSource = this.freshTargetSource();
        //还没有获得接口
        if (this.autodetectInterfaces && this.getProxiedInterfaces().length == 0 && !this.isProxyTargetClass()) {
            Class<?> targetClass = this.getTargetClass();
            if (targetClass == null) {
                throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
            }
//给代理类设置接口
            this.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
        }

        super.setFrozen(this.freezeProxy);
//创建AOP代理
        this.singletonInstance = this.getProxy(this.createAopProxy());
    }

    return this.singletonInstance;
}

ProxyCreatorSupport

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        this.activate();
    }

    return this.getAopProxyFactory().createAopProxy(this);
}

DefaultAopProxyFactory

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    //如果当前配置不需要进一步优化,也不是代理目标类,存在可用的接口
	if (!config.isOptimize() && !config.isProxyTargetClass() 
	&& !this.hasNoUserSuppliedProxyInterfaces(config)) {
    	//创建JDK动态代理
        return new JdkDynamicAopProxy(config);
    } else {
        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.");
        } else {
//如果目标类没有实现接口就创建CGLIB代理,否则创建JDK代理
            return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
        }
    }
}

JDK代理的实现

class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable 

public Object getProxy(ClassLoader classLoader) {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
    }

    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

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;

    Class var10;
    try {
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            Boolean var20 = this.equals(args[0]);
            return var20;
        }

        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            Integer var18 = this.hashCode();
            return var18;
        }

        if (method.getDeclaringClass() != DecoratingProxy.class) {
            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);
//如果拦截器链为空,也就是before、after这些没有配置
//就直接调用目标对象的方法
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            } else {
//如果配置了before、after这些操作,就按照顺序调用这些方法
                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 = AopProxyUtils.ultimateTargetClass(this.advised);
    } finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }

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

    }

    return var10;
}

ReflectiveMethodInvocation

public Object proceed() throws Throwable {
//当前拦截器位置已经到拦截器链的末尾或拦截器链为空
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//调用自身方法
        return this.invokeJoinpoint();
    } else {
        Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
//进行方法和拦截器匹配,匹配成功就调用拦截器的方法,否则递归调用下一个拦截器
            return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
        } else {
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}

总结

这样AOP主要的源码实现我们都看到了,主要的过程是:

  1. 解析配置文件时,将AOP有关配置解析出来,注册到IOC容器中
  2. 从IOC容器获得JavaBean时,会进行判断
  3. 如果JavaBean存在AOP代理,就通过ProxyFactoryBean类来生成AOP的动态代理
  4. 否则就生成CGLIB的动态代理
  5. 然后通过Spring中配置的方法拦截链调用各种拦截方法实现AOP。

今天我们从基本概念和实现,原理和源码角度来剖析了Spring AOP的实现,AOP是Spring非常重要的组成部分,在许多业务中可以给我们提供通用的功能,今天的课程可以帮助大家更加深入理解AOP。
如果你坚持看完了,给自己点个赞吧:)


大家如果需要学习其他Java知识点,戳这里 超详细的Java知识点汇总

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恒哥~Bingo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值