spring 源码解读-AOP

本文深入探讨了Spring AOP的源码实现,从BeanPostProcessor开始,详细阐述了如何在不修改源码的情况下通过预编译和动态代理实现切面编程。讲解了切面、连接点、通知、切点等核心概念,并展示了AOP代理对象的创建过程,特别关注了JDK动态代理在AOP中的应用,以及通知在拦截器链中的执行机制。
摘要由CSDN通过智能技术生成

spring 源码解读-AOP

一、应用场景

AOP(切面编程)是 OOP的延续,可以通过预编译方式和运行期间动态代理实现不修改源码的情况下给程序代码统一增加功能的技术。即业务需求和系统需求分开解耦。例如:日志、事务、安全校验。

二、概念

  • 切面:一个关注点的模块化,这个关注点可能横切多个对象,比如日志输出

  • 连接点:程序执行过程中的行为

  • 通知:切面对连接点所产生的动作,一个切面包括多个通知。

    • 前置通知
    • 后置通知
    • 返回后通知
    • 环绕通知
    • 异常通知
  • 切点:匹配连接点的断言,切面中所有的通知关注的连接点都是由切点表达。

  • 目标对象:被切面所通知的对象。

  • AOP代理对象:JDK和CGLib

三、AOP源码

AOP是通过BeanPostProcessor 后置处理器开始的,bean的后置处理器是一个监听器,可以监听容器触发的Bean生命周期事件,后置处理器向容器注册以后,容器中管理的bean就具备接收IOC容器事件回调能力。

import org.springframework.beans.BeansException;

public interface BeanPostProcessor {

    //bean初始化前提供回调入口
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    //bean初始化之后提供回调入口
    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

1、AbstractAutowireCapableBeanFactory 类对容器生成的bean添加后置处理器

BeanPostProcessor 后置处理器的调用发生在IOC容器完成bean实例对象创建和属性依赖注入完成之后,之前的源码分析中了解,当程序第一次调用getBean()方法向IOC容器获取指定bean时触发创建bean的实例对象然后属性依赖注入,真正的创建bean对象并进行依赖注入的是AbstractAutowireCapableBeanFactory 类的 doCreate()方法。源码如下:

 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {

/**********************创建实例对象start********************************/
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
        Class<?> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                mbd.postProcessed = true;
            }
        }

        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }

            this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
                public Object getObject() throws BeansException {
                    return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        Object exposedObject = bean;
/**********************创建实例对象end********************************/


        try {
        /**********************对bean属性进行依赖注入********************************/
            this.populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
            /***对bean实例对象生成和依赖注入之后,开始bean实例对象的初始化,添加
            BeanPostProcessor 后置处理器****/
                exposedObject = this.initializeBean(beanName, exposedObject, mbd);
            }
        } catch (Throwable var17) {
            if (var17 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var17).getBeanName())) {
                throw (BeanCreationException)var17;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var17);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }

                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
/**********************返回所需的实例对象d********************************/
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

2、initializeBean()方法

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        //jdk安全机制验证权限
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, this.getAccessControlContext());
        } else {
            //为bean包装各种Aware
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        //回调BeanPostProcessors的BeforeInitialization
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }


       //调用bean的 配置的init-method
        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        //回调BeanPostProcessors的AfterInitialization

        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }



 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        //遍历所有的BeanPostProcessors
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if (!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);

        return result;
    }

BeanPostProcessors实现的子类很多,比如:AOP、数据校验等,下面以创建AOP代理对象的子类AbstractAutoProxyCreator类,该类重写了postProcessAfterInitialization()方法。

   public Object postProcessAfterInitialization(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;
        }
    }




    protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        Advisor[] var7 = advisors;
        int var8 = advisors.length;

        for(int var9 = 0; var9 < var8; ++var9) {
            Advisor advisor = var7[var9];
            proxyFactory.addAdvisor(advisor);
        }

        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(this.getProxyClassLoader());
    }

3、整个过程跟踪下来,发现最终调用的是 proxyFactory.getProxy(this.getProxyClassLoader());,这里就能猜测proxyFactory有JDK和CGLib两种,最终调用的是DefaultAopProxyFactory的createAopProxy()方法:

    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 {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

继续跟踪,具体生成代码放在JdkDynamicAopProxy 类中,源码:

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

4、这个就是java 原生的jdk动态代理。那切面是如何织入的?

jdk动态代理,具体的逻辑是在InvocationHandler中,发现JdkDynamicAopProxy 就是InvocationHandler,直接看invoke()方法

  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;

        Object var13;
        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) {
                Class var17 = AopProxyUtils.ultimateTargetClass(this.advised);
                return var17;
            }

            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.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);
            }

            var13 = retVal;
        } finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }

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

        }

        return var13;
    }

实现思路:

  • 首先获取方法的通知链 InterceptChain,如果有通知则应用通知并执行连接点;
  • 如果没有通知,直接反射执行连接点。这里最关键的是通知链 InterceptChain 的获取。

通知链是getInterceptorsAndDynamicInterceptionAdvice方法获取

5、getInterceptorsAndDynamicInterceptionAdvice方法

    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
        AdvisedSupport.MethodCacheKey cacheKey = new AdvisedSupport.MethodCacheKey(method);
        List<Object> cached = (List)this.methodCache.get(cacheKey);
        if (cached == null) {
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }

        return cached;
    }

实际的实现逻辑是由DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法来完成的,且获取的结果会被缓存,下面就是getInterceptorsAndDynamicInterceptionAdvice方法实现:

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

        for(int var10 = 0; var10 < var9; ++var10) {
            Advisor advisor = var8[var10];
            MethodInterceptor[] interceptors;
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    interceptors = registry.getInterceptors(advisor);
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                            MethodInterceptor[] var15 = interceptors;
                            int var16 = interceptors.length;

                            for(int var17 = 0; var17 < var16; ++var17) {
                                MethodInterceptor interceptor = var15[var17];
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        } else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            } else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            } else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

这个方法执行后,advised中配置的连接点或者目标类全部转化为MethodIntercept,继续看下去拦截器链是怎么运行的

      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();
            }

6、如果拦截器链为空,则直接反射调用目标方法,否则创建MethodIntercept,调用其proceed()方法,触发拦截器链执行。

具体的实现类ReflectiveMethodInvocation 中的 proceed() 方法如下:

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

    protected Object invokeJoinpoint() throws Throwable {
        return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
    }

通知拦截器链实际就是责任链模式 顺着拦截器链 递归调用。在往下就是AopUtils.invokeJoinpointUsingReflection

    public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) throws Throwable {
        try {
            ReflectionUtils.makeAccessible(method);
            return method.invoke(target, args);
        } catch (InvocationTargetException var4) {
            throw var4.getTargetException();
        } catch (IllegalArgumentException var5) {
            throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", var5);
        } catch (IllegalAccessException var6) {
            throw new AopInvocationException("Could not access method [" + method + "]", var6);
        }
    }
}

其实就是反射调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值