spring源码---Aop:代理创建

回到wrapIfNecessary()方法中,AbstractAutoProxyCreator类中,现在找到了匹配的Advisor类,开始为bean创建代理:

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
      @Nullable Object[] specificInterceptors, TargetSource targetSource) {
   //1.创建proxyFactory,proxy的生成主要是在proxyFactory中进行
   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);

   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }
   //2.将当前的bean合适的advice,重写封装一下,封装为advisor类,然后添加到ProxyFactory中
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource); //设置代码对象
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   //3.重点,proxyFactory有jdk和cglib两种,使用DefaultAopProxyFactory的createAopProxy()方法进行选择
   return proxyFactory.getProxy(getProxyClassLoader());
}

1.new ProxyFactory() 

  看一下这个类的继承图,父类是ProxyConfig类,它提供的功能就是getProxy()入口,其他主要功能是保存了代理对象的很多信息

                      

3.getProxy()

//位于ProxyFactory类中
public Object getProxy(@Nullable ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

方法拆解,3.1.createAopProxy()方法:来到父类ProxyCreatorSupport类


protected final synchronized AopProxy createAopProxy() {
   return getAopProxyFactory().createAopProxy(this);
}
//深入
public AopProxyFactory getAopProxyFactory() {
   return this.aopProxyFactory;
}
//该字段含义:
private AopProxyFactory aopProxyFactory;
//该字段的初始化:
this.aopProxyFactory = new DefaultAopProxyFactory();

所以,最后调用了DefaultAopProxyFactory类 createAopProxy()方法:

  用来抉择是使用jdk的代理方式,还是cglib的代理方式,传入的参数this:ProxyCreatorSupport类,ProxyFactory类的父类

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   // config.isOptimize()是否使用优化的代理策略,目前使用与CGLIB
   // config.isProxyTargetClass() 是否目标类本身被代理而不是目标类的接口
   // hasNoUserSuppliedProxyInterfaces()是否存在代理接口
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      
      //第二层类的方法,AdvisedSupport类  获得目标代理类的 Class对象   就是目标bean
      Class<?> targetClass = config.getTargetClass();
      //如果实现了接口,则使用jdk代理,如果没有则使用cglib代理
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}

分类标准很简单,如果使用了接口,则使用Jdk的代理方式,否者使用cglib代理方式

3.2 getProxy()

拿到了AopProxy的实现类之后,调用了getProxy()方法:我们使用jdkDynamicAopProxy分析:

初始化方法:将ProxyCreatorSupport类保存,也就是代理工厂

public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
   this.advised = config;
}

    执行getProxy()方法,获取代理类要实现的接口,除了Advised对象中配置的,还会加上SpringProxy,Advised(opaque=false)

    检查得到的接口中没有定义equals或者hashcode接口

public Object getProxy(@Nullable ClassLoader classLoader) {
    //获取完整的 代理 接口
   Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

   该方法的实现是完成走的jdk代理模式,return 中的三个参数是固定的,第一个是加载器,第二个是代理类对应的接口,第三个是this,可以参考代理设计模式:https://blog.csdn.net/W1427259949/article/details/105138669

  JdkDynamicAopProxy类实现了InvocationHandler接口,自然走的是代理模式,核心功能在invoke()方法中,advisor的添加也是在该方法中进行注入:实际上,逻辑应该简单,就是把前面匹配出来的Advisor根据相应的注解对应的位置,加到method.invoke()执行的前后,但是spring中间加了一个advisor转interceptor的过程,所以稍显复杂。

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

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

   try {
      //目标对象未实现equals()方法
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         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);

      //1.  获取可以应用到此方法上的拦截器列表 【入】
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      //2.如果没有可以应用到此方法上的拦截器,则直接反射调用 Method.invoke()
      if (chain.isEmpty()) {
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {//3. 不为空,则逐一调用chain中的每一个拦截方法的proceed()
         //  创建ReflectiveMethodInvocation
         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;
      }
      return retVal;
   }
}

1.拦截器链的获取:this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
   MethodCacheKey cacheKey = new MethodCacheKey(method);
   List<Object> cached = this.methodCache.get(cacheKey);
   if (cached == null) {           //【入】
      cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
            this, method, targetClass);
      this.methodCache.put(cacheKey, cached);
   }
   return cached;
}

继续进入,这里只是一个入口:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
      Advised config, Method method, @Nullable Class<?> targetClass) {

   // This is somewhat tricky... We have to process introductions first,
   // but we need to preserve order in the ultimate list.
   List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
   Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
   //查看是否包含IntroductionAdvisor
   boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
   //这里实际注册了一系列 AdvisorAdapter,用于将Advisor转换成MethodInterceptor
   AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

   for (Advisor advisor : config.getAdvisors()) {
      if (advisor instanceof PointcutAdvisor) {
         // Add it conditionally.
         PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
         if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
            if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
               //将advisor 转换成 Interceptor
               MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
               //检查当前Advisor的切入点,是否可以匹配当前方法
               if (mm.isRuntime()) {
                  // Creating a new object instance in the getInterceptors() method
                  // isn't a problem as we normally cache created chains.
                  for (MethodInterceptor interceptor : interceptors) {
                     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)) {
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
         }
      }
      else {
         Interceptor[] interceptors = registry.getInterceptors(advisor);
         interceptorList.addAll(Arrays.asList(interceptors));
      }
   }

   return interceptorList;
}

获得拦截器链之后,开始执行

2.无拦截器,直接执行方法

public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) {
   // Use reflection to invoke the method.
   try {
      ReflectionUtils.makeAccessible(method);
      return method.invoke(target, args);
   }
}

3.执行拦截器链

public Object proceed() throws Throwable {
   //如果拦截器执行完了,则执行拦截点
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }

   Object interceptorOrInterceptionAdvice =
         this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      InterceptorAndDynamicMethodMatcher dm =
            (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      //动态匹配,运行时参数是否满足条件
      if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
         return dm.interceptor.invoke(this);
      }
      else { //动态匹配失败,略过当前拦截器,执行下一个
         return proceed();
      }
   }
   else { //执行当前拦截器
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
   }
}

链路的执行,向栈一样,递归调用方法,而不是简单的for()循环调用,比如AfterReturningAdviceInterceptor类中:

public Object invoke(MethodInvocation mi) throws Throwable {
   Object retVal = mi.proceed(); //先递归调用,
    //调用完毕之后,再需要方法
   this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
   return retVal;
}

而MethodBeforeAdviceInterceptor类中,它的方法就是先调用的

public Object invoke(MethodInvocation mi) throws Throwable {
   this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
   return mi.proceed();
}

到这里,aop的原理,我们就告一段落了!

 参考链接:https://blog.csdn.net/qq_26323323/article/details/81012855

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值