spring 源码之AOP 创建代理 createProxy (九)

上一篇 我们解析了,AOP 创建切面的过程,今天我们解析,创建切面完成后开始正式创建代理类的过程。

1、从这里入口:AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware   的方法开始-->

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

   //改bean收集相关的的advisors   
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   //如果有advisors 切面,则生成该bean的代理
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //把被代理对象bean实例封装到SingletonTargetSource对象中,这里正式创建bean的代理对象。点击进入-->
      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;
}

点击来到:

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)) {
         //proxyTargetClass 是否对类进行代理,而不是对接口进行代理,设置为true时,使用CGLib代理。
        //设置false 是 jdk 代理 类似xml 配置:  
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   //把advice类型的增强包装成advisor切面
   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   proxyFactory.addAdvisors(advisors);
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   //用来控制代理工厂被配置后,是否还允许修改代理的配置,默认为false
   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }

   //获取代理实例,点击进入-->
   return proxyFactory.getProxy(getProxyClassLoader());
}

2、来到  ProxyFactory extends ProxyCreatorSupport 类的  getProxy 方法

public Object getProxy(@Nullable ClassLoader classLoader) {
   //根据目标对象是否有接口来判断采用什么代理方式,cglib代理还是jdk动态代理
   return createAopProxy().getProxy(classLoader);//ctrl+t 点击显示--->
}

spring 源码之AOP 创建代理 createProxy (九)_第1张图片

 

3、这里jdk 动态代理为例  进入   JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable  的

getProxy方法:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
   if (logger.isTraceEnabled()) {
      logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
   }
   //advised是代理工厂对象
   Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   //这个方法里面,就通过构造器,生成了完整的代理对象。
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

4、现在我们开始调用该代理对象,当发生代理对象调用时,肯定会调用到实现了 invocationHandler 接口的类,假如以jdk代理为例,就会进入到这个类就是:JdkDynamicAopProxy,也一定会调到该类的 invoke 方法 (前篇文章详解过jdk代理,可以看看原理:https://blog.csdn.net/nandao158/article/details/105622444

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

   //从代理工厂中拿到TargetSource对象,该对象包装了被代理实例bean
   TargetSource targetSource = this.advised.targetSource;
   Object target = null;

   try {
      //被代理对象的equals方法和hashCode方法是不能被代理的,不会走切面
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
         // The target does not implement the equals(Object) method itself.
         return equals(args[0]);
      }
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
         // The target does not implement the hashCode() method itself.
         return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
         // There is only getDecoratedClass() declared -> dispatch to proxy config.
         return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass().isAssignableFrom(Advised.class)) {
         // Service invocations on ProxyConfig with the proxy config...
         return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }

      Object retVal;

      if (this.advised.exposeProxy) {
         // Make invocation available if necessary.
         oldProxy = AopContext.setCurrentProxy(proxy);
         setProxyContext = true;
      }

      // Get as late as possible to minimize the time we "own" the target,
      // in case it comes from a pool.
      //这个target就是被代理实例
      target = targetSource.getTarget();
      Class targetClass = (target != null ? target.getClass() : null);

      // Get the interception chain for this method.
      //从代理工厂中拿过滤器链 Object是一个MethodInterceptor类型的对象,其实就是一个advice对象,
//这里是一个重要分支,今天介绍 ,点击进入-->
      List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      // Check whether we have any advice. If we don't, we can fallback on direct
      // reflective invocation of the target, and avoid creating a MethodInvocation.

      //如果该方法没有执行链,则说明这个方法不需要被拦截,则直接反射调用
      if (chain.isEmpty()) {
         // We can skip creating a MethodInvocation: just invoke the target directly
         // Note that the final invoker must be an InvokerInterceptor so we know it does
         // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
         // We need to create a method invocation...
         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())) {
         // Special case: it returned "this" and the return type of the method
         // is type-compatible. Note that we can't help if the target sets
         // a reference to itself in another returned object.
         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()) {
         // Must have come from TargetSource.
         targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
         // Restore old proxy.
         AopContext.setCurrentProxy(oldProxy);
      }
   }
} 
  

5、来到 AdvisedSupport extends ProxyConfig implements Advised 类的   getInterceptorsAndDynamicInterceptionAdvice 方法:

public List getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class targetClass) {
   MethodCacheKey cacheKey = new MethodCacheKey(method);
   List cached = this.methodCache.get(cacheKey);
   if (cached == null) {
      //获取过滤器链,点击进入接口后,ctrl+t 进入-->
      cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
            this, method, targetClass);
      this.methodCache.put(cacheKey, cached);
   }
   return cached;
} 
  

6、进入 DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable  类的 

getInterceptorsAndDynamicInterceptionAdvice 方法:
@Override
public List 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.
   AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
   //从代理工厂中获得该被代理类的所有切面advisor,config就是代理工厂对象
   Advisor[] advisors = config.getAdvisors();
   List interceptorList = new ArrayList<>(advisors.length);
   Class actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
   Boolean hasIntroductions = null;

   for (Advisor advisor : advisors) {
      //绝大部分走这里
      if (advisor instanceof PointcutAdvisor) {
         // Add it conditionally.
         PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
         //如果切面的pointCut和被代理对象是匹配的,说明是切面要拦截的对象
         if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
            MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
            boolean match;
            if (mm instanceof IntroductionAwareMethodMatcher) {
               if (hasIntroductions == null) {
                  hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
               }
               match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
            }
            else {
               //接下来判断方法是否是切面pointcut需要拦截的方法
               match = mm.matches(method, actualClass);
            }
            //如果类和方法都匹配
            if (match) {

               //获取到切面advisor中的advice,并且包装成MethodInterceptor类型的对象
               MethodInterceptor[] interceptors = registry.getInterceptors(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;
}
 
  

7、这里正式获取到过滤器执行链,注释写的清楚,大家可以详细看看,下一篇我们正式介绍,执行这些切面执行链的流程,通过拦截器链继续到连接点,很重要,敬请期待!。

 

你可能感兴趣的:(spring源码学习,spring)