栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring AOP原理 应用增强创建代理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring AOP原理 应用增强创建代理

以下源代码基于Spring aop 5.2.0

经过上篇的长篇大论分析Spring AOP原理 收集切面和实例化增强器_Alan CGH的博客-CSDN博客,我们知道了Spring是如何收集切面类并把其中的增强方法封装成增强器的。然后筛选出适用于bean的增强器数组返回。其实上一篇写的太过细节了,本篇不会再深入细节,重点放在逻辑流程上。

整个AOP代理对象的工作入口发生于AbstractAutoProxyCreator类,它同时是InstantiationAwareBeanPostProcessor,在bean的加载过程中的bean实例化前,resolveBeforeInstantion()逻辑中触发AutoProxyCreator的后置处理。所以线程会执行到这里来。在对bean收集到可适用的增强器后就是创建代理对象的工作。

1. AutoProxyCreator.getAdvicesAndAdvisorsForBean() 之后,创建代理对象
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的增强器,这回跑不掉了,要创建代理对象返回。

   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

   if (specificInterceptors != DO_NOT_PROXY) {

      this.advisedBeans.put(cacheKey, Boolean.TRUE);

        // 1.1 根据用户配置选择合适的代理策略

      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;

}

1.1 将增强器转成统一的Advisor接口。初始化ProxyFactory对象,用它选择代理策略创建代理。

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

      }

   }

// AOP的增强器实现对象各有不同,需要统一转成Advisor接口,为了方便叙述还是称其为增强器

   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

// 给代理工厂传入增强器

   proxyFactory.addAdvisors(advisors);

// 给代理工厂指定要代理的目标对象

   proxyFactory.setTargetSource(targetSource);

// 模板方法设计模式运用,留给子类自定义代理工厂的机会

   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);

   if (advisorsPreFiltered()) {

      proxyFactory.setPreFiltered(true);

   }

// 1.2 创建代理

   return proxyFactory.getProxy(getProxyClassLoader());

}


1.2 根据配置选择代理模式,创建代理

public Object getProxy(@Nullable ClassLoader classLoader) {

// 1.3 createAopProxy() 选择代理模式

// 1.4 getProxy() 创建代理对象

   return createAopProxy().getProxy(classLoader);

}

1.3 选择代理模式,CGLIB代理还是JDK代理。在用户配置文件中的proxyTargetClass属性在此生效,proxy-target-class是指是否直接代理目标对象的Class对象,proxy-target-class=true时会优先选择CGLIB生成子类直接继承目标类Class对象。除非目标类本身是final或目标类是接口或已经是代理对象。

@Override

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

   if (!IN_NATIVE_IMAGE &&

         (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {

      // 要代理的目标对象的Class对象

      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() || Proxy.isProxyClass(targetClass)) {

         return new JdkDynamicAopProxy(config);

      }

      return new ObjenesisCglibAopProxy(config);

   }

   else {

      return new JdkDynamicAopProxy(config);

   }

}

1.4 getProxy() 创建代理对象。根据上一步知道创建代理对象有2条分支

CGLIB创建代理

创建完毕代理对象后,那么CGLIB代理对象怎么调用目标对象的目标方法呢?

CGLIB的关键是MethodInterceptor,给代理对象注入callback[]时,将适用于代理对象的advised增强器配置对象封装成DynamicAdvisedInterceptor对象,它实现了MethodInterceptor接口。让后将DynamicAdvisedInterceptor加入callback[]。调用代理对象的方法时,所有方法被转发到拦截器链的intercept()方法。advised变量就是AdvisedSupport类是AOP配置对象,里面封装有适用bean的增强器链。

@Override

@Nullable

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

   Object oldProxy = null;

   boolean setProxyContext = false;

   Object target = null;

   TargetSource targetSource = this.advised.getTargetSource();

   try {

      // expose-proxy属性生效。原理是每次方法执行时将代理对象放入线程的LocalMap中。每次拦截器和方法执行完毕再移除

      if (this.advised.exposeProxy) {

         oldProxy = AopContext.setCurrentProxy(proxy);

         setProxyContext = true;

      }

      target = targetSource.getTarget();

      Class targetClass = (target != null ? target.getClass() : null);

      // 将增强器做成链

      List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      Object retVal;

      // Check whether we only have one InvokerInterceptor: that is,

      // no real advice, but just reflective invocation of the target.

      if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {

         // 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 = methodProxy.invoke(target, argsToUse);

      }

      else {

         // 增强器链非空。创建ReflectiveMethodInvocation对象执行增强器链。该方法的增强方法都会在这里执行

         retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

      }

      retVal = processReturnType(proxy, target, method, retVal);

      return retVal;

   }

   finally {

      if (target != null && !targetSource.isStatic()) {

         targetSource.releaseTarget(target);

      }

      if (setProxyContext) {

         // Restore old proxy.

         AopContext.setCurrentProxy(oldProxy);

      }

   }

}


 

最后来看看JDK代理对象

Spring创建的JdkDynamicAopProxy是直接实现了InvocationHandler接口。handler是链接代理对象和目标对象的中间桥梁。代理对象所有方法调用被转发到invoke(),所以在invoke()中实现了增强器的执行和目标方法的执行。

所有代理对象的被增强过的方法调用时,都会先来到这里

@Override

@Nullable

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 {

      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) {

         // expose proxy生效

         oldProxy = AopContext.setCurrentProxy(proxy);

         setProxyContext = true;

      }

      target = targetSource.getTarget();

      Class targetClass = (target != null ? target.getClass() : null);

      // 拿到方法的增强器链

      List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      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 {

         // 创建增强器链,链式执行。各增强器自己维护和目标方法的顺序,即是先执行增强方法还是先执行目标方法。

         MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

         retVal = invocation.proceed();

      }

      // 省略代码..

      return retVal;

   }

   finally {

      if (target != null && !targetSource.isStatic()) {

         // Must have come from TargetSource.

         targetSource.releaseTarget(target);

      }

      if (setProxyContext) {

         // Restore old proxy.

         AopContext.setCurrentProxy(oldProxy);

      }

   }

} 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号