spring系列文章(一)AOP源码分析

BeanNameAutoProxyCreator与ProxyFactoryBean区别

我们项目用到的是BeanNameAutoProxyCreator,说道aop可能大家更熟悉的是ProxyFactoryBean。它们的区别很简单,BeanNameAutoProxyCreator只不过可以配置多个target

使用

配置中有两个参数:

  • beanNames:要拦截的bean
  • interceptorNames:拦截器

配置示例:

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator" id="ims_core_new_ServiceAutoProxy">
        <property name="beanNames">
            <list>
                <!--需要拦截的服务-->
                <value>imsinner_innerService</value>
                <value>imsinner_innerQueryService</value>
                <value>imssdl_iImsSyncAppService</value>
                <value>imsts_iImsTsAppService</value>
                <value>imsxdr_iImsXdrService</value>
            </list>
        </property>
        <property name="interceptorNames">
            <list>
                <value>ims_new_interceptor</value>
            </list>
        </property>
    </bean>

源码分析

那么重点就是来看下BeanNameAutoProxyCreator了

public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
}

AbstractAutoProxyCreator里几个重要的属性

private String interceptorNames[];
private BeanFactory beanFactory;
private ClassLoader proxyClassLoader;

凭直觉,createProxy应该是一个重要的方法,分析一下

  protected Object createProxy(Class beanClass, String beanName, Object specificInterceptors[], TargetSource targetSource)
    {
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if(!shouldProxyTargetClass(beanClass, beanName))
        {
            Class targetInterfaces[] = ClassUtils.getAllInterfacesForClass(beanClass, proxyClassLoader);
            Class aclass[];
            int k = (aclass = targetInterfaces).length;
            for(int i = 0; i < k; i++)
            {
                Class targetInterface = aclass[i];
                proxyFactory.addInterface(targetInterface);
            }

        }
        Advisor advisors[] = buildAdvisors(beanName, specificInterceptors);
        Advisor aadvisor[];
        int l = (aadvisor = advisors).length;
        for(int j = 0; j < l; j++)
        {
            Advisor advisor = aadvisor[j];
            proxyFactory.addAdvisor(advisor);
        }

        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(freezeProxy);
        if(advisorsPreFiltered())
            proxyFactory.setPreFiltered(true);
        return proxyFactory.getProxy(proxyClassLoader);
}

一路追踪到了这个方法

    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);
            if(!cglibAvailable)
                throw new AopConfigException("Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.");
            else
                return CglibProxyFactory.createCglibProxy(config);
        } else
        {
            return new JdkDynamicAopProxy(config);
        }
    }

JdkDynamicAopProxy 的getProxy如下

public Object getProxy(ClassLoader classLoader)
    {
        if(logger.isDebugEnabled())
            logger.debug((new StringBuilder("Creating JDK dynamic proxy: target source is ")).append(advised.getTargetSource()).toString());
        Class proxiedInterfaces[] = AopProxyUtils.completeProxiedInterfaces(advised);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

到这里我们就看到了创建jdk的proxy代理

这里我们的JdkDynamicAopProxy实现了InvocationHandler这个接口,this参数对应的是InvocationHandler对象,也就是说当 Proxy对象的函数被调用的时候,InvocationHandler的invoke方法会被作为回调函数调用:下面也有一个回调的分析。

分析到这里关键就看下invoke方法了

这里得到一个拦截器链

List chain = advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if(chain.isEmpty())
        {
            //如果拦截器为空,则直接调用被代理的方法
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
        } else
        {
//拦截器不为空,则 
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
            retVal = invocation.proceed();
        }
  public static Object invokeJoinpointUsingReflection(Object target, Method method, Object args[])
        throws Throwable
    {
        ReflectionUtils.makeAccessible(method);
        return method.invoke(target, args);
        InvocationTargetException ex;
        ex;
        throw ex.getTargetException();
        ex;
        throw new AopInvocationException((new StringBuilder("AOP configuration seems to be invalid: tried calling method [")).append(method).append("] on target [").append(target).append("]").toString(), ex);
        ex;
        throw new AopInvocationException((new StringBuilder("Could not access method [")).append(method).append("]").toString(), ex);
    }
  public Object proceed()
        throws Throwable
{
    //已经没有拦截器要调用了,则直接调用主方法
        if(currentInterceptorIndex == interceptorsAndDynamicMethodMatchers.size() - 1)
            return invokeJoinpoint();
        Object interceptorOrInterceptionAdvice = interceptorsAndDynamicMethodMatchers.get(++currentInterceptorIndex);
        if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher)
        {
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
            if(dm.methodMatcher.matches(method, targetClass, arguments))
                return dm.interceptor.invoke(this);
            else
                return proceed();
        } else
        {
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
}

这里有一个什么匹配的逻辑,如果匹配,调用这个拦截器,如果不匹配,继续下一个拦截器,这个匹配就不细看了

那如果匹配了,下一个就不走了?
挺关键的这个地方,这个ReflectiveMethodInvocation实现了MethodInvocation接口,在调用拦截器的invoke的方法的时候,把自己做为参数传给了拦截器,在拦截器A执行完以后,如果想继续执行拦截器链的下一个,只需要在它实现的invoke方法的proceed方法,就可以回调proceed,继续执行下一个

   return dm.interceptor.invoke(this);

   public Object invoke(MethodInvocation invocation) throws Throwable

总结

在整个的分析过程中,可以看到理解了这么几个技术点,基本上就理解了AOP

  • 动态代理
  • 责任链
  • 回调

当然还有spring最基本的工厂模式,太基本了就不罗列它了。

    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/flying_panda/article/details/46917233
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞