AOP是 Aspect Oriented Programming 的缩写,意思是面向切面编程

          可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP 设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP 可以说也是这种目标的一种实现。 我们现在做的一些非业务,如:日志、事务、安全等都会写在业务代码中(也即是说,这些非业务类横切 于业务类),但这些代码往往是重复,复制——粘贴式的代码会给程序的维护带来不便,AOP 就实现了 把这些业务需求与系统需求分开来做。这种解决的方式也称代理机制。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

         Spring 的 AOP 中有个核心接口 BeanPostProcessor(后置处理器),它是 Spring IOC 容器经常使用到的一个特性,这个 Bean 后置处理器是一个监听器,可以监听容器触发的 Bean 声明周期事件。后置处理器向容器注册以后,容器中管理的 Bean 就具备了接收 IOC 容器事件回调的能力

概念东西不多说了,直入正题

因为Spring框架本身的复杂度,细节没有过多纠结,纠结太多 我自己 就晕了,能力有限

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

BeanPostProcessor 接口只定义了两个default方法,后面马上会提到

public interface BeanPostProcessor {
    //为在Bean的初始化前提供回调入口
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    //为在Bean的初始化之后提供回调入口
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

 

IOC和AOP容器核心类--->>>AbstractAutowireCapableBeanFactory 

initializeBean()方法作为分析AOP的入口

    //初始容器创建的Bean实例对象,为其添加BeanPostProcessor后置处理器
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        //JDK的安全机制验证权限
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        } else {
            //为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        //对BeanPostProcessor后置处理器的postProcessBeforeInitialization
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        //调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
        //文件中通过init-method属性指定的
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        //对BeanPostProcessor后置处理器的postProcessAfterInitialization
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

继续--->>>

    //调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            //调用Bean实例所有的后置处理中的初始化前处理方法
            Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

 

    //调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
            //调用Bean实例所有的后置处理中的初始化后处理方法
            Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

这两个方法刚好和开篇提到的BeanPostProcessor 中的两个方法对应

Spring AOP源码分析 随笔 第1张

applyBeanPostProcessorsAfterInitialization 调用 postProcessAfterInitialization 继续跟代码

继续--->>>AbstractAutoProxyCreator

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
        }
继续--->>>wrapIfNecessary方法
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;}
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean; }
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;}
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
 Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

继续--->>>createProxy方法

  
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable 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 (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        return proxyFactory.getProxy(getProxyClassLoader());
    }
 

继续--->>>proxyFactory.getProxy方法

进入ProxyFactory中

    public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
createAopProxy方法
Spring AOP源码分析 随笔 第2张

两种动态代理的方式JDK和Cglib

最终获得expose对象即动态代理对象

exposedObject = initializeBean(beanName, exposedObject, mbd);

再来分析JdkDynamicAopProxy(implement InvocationHandler)

Spring AOP源码分析 随笔 第3张

方法调用时,了解JDK原生动态代理的都知道实际方法执行过程中就会调用invoke()方法

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;

        TargetSource targetSource = this.advised.targetSource;
        Object target = null;

        try {
            //eqauls()方法,具目标对象未实现此方法
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // The target does not implement the equals(Object) method itself.
                return equals(args[0]);
            }
            //hashCode()方法,具目标对象未实现此方法
            else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                return hashCode();
            }
            else if (method.getDeclaringClass() == DecoratingProxy.class) {
                return AopProxyUtils.ultimateTargetClass(this.advised);
            }
            //Advised接口或者其父接口中定义的方法,直接反射调用,不应用通知
            else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            }

            Object retVal;

            if (this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            //获得目标对象的类
            target = targetSource.getTarget();
            Class<?> targetClass = (target != null ? target.getClass() : null);

            //获取可以应用到此方法上的Interceptor列表
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            //如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
            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);
                // 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 != 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);
            }
            return retVal;
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                AopContext.setCurrentProxy(oldProxy);
            }
        }
      }

继续--->>>processd

进入ReflectiveMethodInvocation

    public Object proceed() throws Throwable {//如果Interceptor执行完了,则执行joinPoint
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//此处才是最纯粹的方法调用
return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); //如果要动态匹配joinPoint if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; //动态匹配:运行时参数是否满足匹配条件 if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else {//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor return proceed(); } } else {//执行当前Intercetpor return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }

首先获得InterceptorAndDynamicMethodMatcher中的interceptor,interceptor可能存在多种不同的实现,分析其中两种比较典型的(MethodBeforeAdviceInterceptorAfterReturningAdviceInterceptor

Spring AOP源码分析 随笔 第4张

Spring AOP源码分析 随笔 第5张

类似递归调用,开始跨过了山和大海(beforeMethod)

到达

Spring AOP源码分析 随笔 第6张

然后继续跨过山和大海(afterMethod)

 当然InterceptorAndDynamicMethodMatcher种的intercepter不只两种,还有ThrowsAdviceInterceptor...等,他们的功能可以分为5种(方法前置,方法后置,方法返回,方法异常,方法环绕)。

 

 

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄