zoukankan      html  css  js  c++  java
  • spring中代理的创建

    spring 代理的创建


    spring 中创建代理使用了 Jdk 和 Cglib 两种方式创建,JdkDynamicAopProxyObjenesisCglibAopProxy,通过使用配置 AdvisedProxyConfig来管理配置,根据配置决定使用哪种方式创建代理,下面来介绍这几个关键的类。

    Advised

    ​ Advised 是一个管理 AOP 代理工厂配置的接口,在spring中的所有AopProxy都可以转换为 Advised。

    ProxyConfig

    在 spring 中,使用 ProxyConfig 来配置代理创建属性。

    /**
     * 代理工厂的超类,用于统一管理代理工厂类的属性。
     */
    public class ProxyConfig implements Serializable {
       // true:使用子类代理,false:使用接口代理
       private boolean proxyTargetClass = false;
       // 启动代理优化
       private boolean optimize = false;
       // 使用该代理工长创建的代理是否可以转换为 Advised,默认为false:表示可以,
       // 如果为false,可以将bean转换为Advised:Advised testBean  = (Advised) context.getBean("testBean");
       boolean opaque = false;
       // 将代理暴露出去,绑定到 ThreadLocal 的 currentProxy,用于代理类自己的方法调用自己的场景。
       boolean exposeProxy = false;
       // 冻结配置,true:不能修改该代理工长的配置。
       private boolean frozen = false;
    }
    

    实现了ProxyConfig 的直接子类有4个:

    ScopedProxyFactoryBean、ProxyProcessorSupport、AbstractSingletonProxyFactoryBean、AdvisedSupport,这几个类使用不同的方式来创建代理,但是最后还是会将创建代理的工作委托给 ProxyFactory,下面来查看4个直接子类的相关代码。

    1. ScopedProxyFactoryBean:用于@Scope 注解,实现bean的作用域控制。他实现了 BeanFactoryBeanFactoryAware接口,具有创建、管理bean的能力。

      这个类生成的代理只会记录类的名称,然后根据作用域获取bean,如果是prototype的,则beanFactory会创建一个新的bean。

      public class ScopedProxyFactoryBean extends ProxyConfig
            implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean{
      
          // 使用它来管理bean的作用域,他的实现很简答,就是获取对象时,委托给 beanFactory,然后 beanFactory 根据作用域获取对应的bean。
          private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();
          @Override
      	public void setBeanFactory(BeanFactory beanFactory) {
      		if (!(beanFactory instanceof ConfigurableBeanFactory)) {
      			throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);
      		}
      		ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
      		
              // 将beanFactory 与 scopedTargetSource 关联,获取代理目标类时,从 scopedTargetSource 中获取,
              // SimpleBeanTargetSource 将获取bean的操作委托给了beanFactory
      		this.scopedTargetSource.setBeanFactory(beanFactory);
      		
      		ProxyFactory pf = new ProxyFactory();
      		pf.copyFrom(this);
      		pf.setTargetSource(this.scopedTargetSource);
      
      		Assert.notNull(this.targetBeanName, "Property 'targetBeanName' is required");
      		Class<?> beanType = beanFactory.getType(this.targetBeanName);
      		if (beanType == null) {
      			throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName +
      					"': Target type could not be determined at the time of proxy creation.");
      		}
              // 使用接口代理
      		if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) {
      			pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader()));
      		}
      		// 简单的代理增强,在调用代理类时,从 beanFactory 中获取bean进行调用,这样就做到作用域的控制了。
      		ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());
      		pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));
      		
              // 标记代理需要不需要被AOP拦截,及时有切入点匹配 
      		pf.addInterface(AopInfrastructureBean.class);
      
              // 创建代理对像:将创建代理交给 ProxyFactory
      		this.proxy = pf.getProxy(cbf.getBeanClassLoader());
      	}
      }
      
    2. ProxyProcessorSupport:为 ProxyFactory 提供了常用的公共方法。

    public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {
        /**
         * 可以自定义排序
         */
        public void setOrder(int order) { this.order = order; }
    	@Override
    	public int getOrder() { return this.order; }
        
        /**
         * 当实现了接口时,使用接口代理,没有实现接口则使用类代理。
         */
        protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
    		Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
    		boolean hasReasonableProxyInterface = false;
    		for (Class<?> ifc : targetInterfaces) {
    			if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
    					ifc.getMethods().length > 0) {
    				hasReasonableProxyInterface = true;
    				break;
    			}
    		}
    		if (hasReasonableProxyInterface) {
    			for (Class<?> ifc : targetInterfaces) {
    				proxyFactory.addInterface(ifc);
    			}
    		}
    		else {
    			proxyFactory.setProxyTargetClass(true);
    		}
    	}
    }
    
    1. AbstractSingletonProxyFactoryBean : 创建单例代理对象,在需要代理的对象实例化后,使用 InitializingBean#afterPropertiesSet()来创建代理,并为其设置前置通知和后置通知。

      public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
      		implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean {
      	// 代理目标对象
          private Object target;
      
      	// 需要代理的接口
      	private Class<?>[] proxyInterfaces;
      
      	// 前置拦截器
      	private Object[] preInterceptors;
      
      	// 后置拦截器
      	private Object[] postInterceptors;
      
      	// 全局 Advisor 注册器
      	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
      
      	// 类加载器
      	private transient ClassLoader proxyClassLoader;
      
      	// 代理对象
      	private Object proxy;
          
          // 实例化之后调用
          @Override
      	public void afterPropertiesSet() {
              // ....
      
              // 将代理创建工作委托给 ProxyFactory
      		ProxyFactory proxyFactory = new ProxyFactory();
      
              // 将预处理器、主处理器、后置处理器按顺序添加,可以组成一个处理器链根据添加顺序来执行所有的处理器。
              // 添加预处理器
      		if (this.preInterceptors != null) {
      			for (Object interceptor : this.preInterceptors) {
      				proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
      			}
      		}
              // 添加主要的处理器,交给子类实现
      		proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
              // 添加后置处理器
      		if (this.postInterceptors != null) {
      			for (Object interceptor : this.postInterceptors) {
      				proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
      			}
      		}
              // 复制属性
      		proxyFactory.copyFrom(this);
      		// 创建代理目标源:默认是 SingletonTargetSource 
      		TargetSource targetSource = createTargetSource(this.target);
      		proxyFactory.setTargetSource(targetSource);
      
              // 设置代理的接口
      		if (this.proxyInterfaces != null) {
      			proxyFactory.setInterfaces(this.proxyInterfaces);
      		}
              // 如果没有使用类代理的方式,解析目标类的接口。
      		else if (!isProxyTargetClass()) {
      			// Rely on AOP infrastructure to tell us what interfaces to proxy.
      			Class<?> targetClass = targetSource.getTargetClass();
      			if (targetClass != null) {
      				proxyFactory.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
      			}
      		}
      		
              // 代理工厂后置处理方法,由子类实现,更改代理配置
      		postProcessProxyFactory(proxyFactory);
              // 创建代理对象,委托给了 ProxyFactory
      		this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
      	}
      }		
      
    2. AdvisedSupport:实现了 Advised,将 ProxyConfigAdvised进行适配,为 Advised 提供了支持,他的唯一子类 ProxyCreatorSupport为创建代理提供了支持。

      public class AdvisedSupport extends ProxyConfig implements Advised {
          // 空代理对象
      	public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE;
      	// 代理目标源:默认为空目标源
      	TargetSource targetSource = EMPTY_TARGET_SOURCE;
      	// 是否已经对Advisors进行了过虑
      	private boolean preFiltered = false;
          // Advisor 调用链工长
      	AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
      	// 缓存方法对应的 Advisor 调用链。
      	private transient Map<MethodCacheKey, List<Object>> methodCache;
      	// 要实现的代理接口,按顺序存储。
      	private List<Class<?>> interfaces = new ArrayList<>();
      	// Advisor 列表
      	private List<Advisor> advisors = new ArrayList<>();
      	// Advisor 数据,为了方便内部操作。
      	private Advisor[] advisorArray = new Advisor[0];
      }
      

      ProxyCreatorSupport 为创建代理提供了支持,他使用了AopProxyFactory 来创建AopProxy,最后ProxyFactory使用 AopProxy来创建代理对象。

      在创建ProxyCreatorSupport 时默认创建 DefaultAopProxyFactory,由他来判断使用接口代理还是子类代理。

      public class ProxyCreatorSupport extends AdvisedSupport {
      	private AopProxyFactory aopProxyFactory;
      
      	private final List<AdvisedSupportListener> listeners = new LinkedList<>();
      
          // 在创建第一个代理后将置为true,表示进入活动状态,将会触发 listeners。
      	private boolean active = false;
          
        	/**
        	 * 无参构造器,将会创建一个默认的aopProxyFactory。
        	 * DefaultAopProxyFactory 是一个创建代理的工长,用于根据配置创建代理。
        	 */
          public ProxyCreatorSupport() {
      		this.aopProxyFactory = new DefaultAopProxyFactory();
      	}
          
          // 创建AOP代理,根据自身的配置属性觉得使用JDK代理还是Cglib代理。
          protected final synchronized AopProxy createAopProxy() {
      		if (!this.active) {
      			activate();
      		}
      		return getAopProxyFactory().createAopProxy(this);
      	}
      }
      

      ​ 上面提到使用 DefaultAopProxyFactory 来决定使用 jdk代理还是 Cglib代理,他通过接收一个 AdvisedSupport

      // AopProxy 工厂
      public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
      
      	@Override
      	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.");
      			}
                  // 代理目标是接口,或者也是一个代理对象,使用jdk代理,否则使用Cglib 代理
      			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
      				return new JdkDynamicAopProxy(config);
      			}
      			return new ObjenesisCglibAopProxy(config);
      		}
              // 使用接口代理:JDK代理 
      		else {
      			return new JdkDynamicAopProxy(config);
      		}
      	}
      }
      

      ProxyFactoryProxyCreatorSupport 的子类,通过调用父类的方法获取AopProxy来创建目标代理对象。

      public class ProxyFactory extends ProxyCreatorSupport {
          public Object getProxy() {
              // 掉用 `ProxyCreatorSupport#createAopProxy` 方法之后根据配置来判断使用 JDK生成代理还是 Cglib生成代理
      		return createAopProxy().getProxy();
      	}
          // 与上面的方法区别在于传入了类加载器
      	public Object getProxy(@Nullable ClassLoader classLoader) {
      		return createAopProxy().getProxy(classLoader);
      	}
      }
      
    JdkDynamicAopProxy
    final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    	/** 代理配置. */
    	private final AdvisedSupport advised;
    
    	/**
    	 * 代理的接口上是否定义了equals方法
    	 */
    	private boolean equalsDefined;
    
    	/**
    	 * 代理的接口是否定义了hashCode 方法
    	 */
    	private boolean hashCodeDefined;
        
        public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
    		Assert.notNull(config, "AdvisedSupport must not be null");
            // 通知不为空,并且目标源不为空。
    		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
    			throw new AopConfigException("No advisors and no TargetSource specified");
    		}
    		this.advised = config;
    	}
    
    	// 创建代理
    	@Override
    	public Object getProxy() {
            // 传入默认类加载器
    		return getProxy(ClassUtils.getDefaultClassLoader());
    	}
    	
    	@Override
    	public Object getProxy(@Nullable ClassLoader classLoader) {
    		if (logger.isTraceEnabled()) {
    			logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
    		}
            // 获取代理目标类的所有接口
    		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
            // 检查接口是否实现了equals 和 hashCode 方法
    		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
            // 创建代理对象,这里传入了this对象,因为 JdkDynamicAopProxy 实现了 InvocationHandler,使用这一段代理逻辑进行代理
    		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    	}
        
        /**
         * aop代理使用jdk代理将执行的逻辑
         */
        @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 {
               	// 执行equals方法时,接口未定义 equals 方法 ,执行JdkDynamicAopProxy 的 equals 方法
    			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
    				return equals(args[0]);
    			}
                //  执行 hashCode 方法时,接口未定义 hashCode 方法,执行JdkDynamicAopProxy的hashCode方法
    			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
    				return hashCode();
    			}
                // 
    			else if (method.getDeclaringClass() == DecoratingProxy.class) {
    				return AopProxyUtils.ultimateTargetClass(this.advised);
    			}
               	// 能够转换为Advised,将转换为Advised,然后执行
    			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
    					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
    				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
    			}
    
    			Object retVal;
    			// 是否暴露当前的代理,绑定到ThreadLocal中,
    			if (this.advised.exposeProxy) {
    				oldProxy = AopContext.setCurrentProxy(proxy);
    				setProxyContext = true;
    			}
    			// 获取目标对象
    			target = targetSource.getTarget();
    			Class<?> targetClass = (target != null ? target.getClass() : null);
    
                // 根据代理目标对象和方法获取切入点、方法拦截器等。
    			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    			
                // 如果与该方法匹配的拦截器或通知为空,则进行直接调用,避免创建MethodInvocation
    			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);
    				retVal = invocation.proceed();
    			}
    			// 
    			Class<?> returnType = method.getReturnType();
                // 如果返回值是目标对象,并且代理对象是返回值类型的一个实例,则将返回值替换为代理对象
                // 方法的声明类未实现 RawTargetAccess
    			if (retVal != null && retVal == target &&
    					returnType != Object.class && returnType.isInstance(proxy) &&
    					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
    				retVal = proxy;
    			}
                // 如果返回值类型时基础数据类型,并且为null。
    			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);
    			}
    		}
    	}
    }
    

    JdkDynamicAopProxy 中,有2处关键代码,1是获取代理目标的接口,2是执行切入点、拦截器。

    1. AopProxyUtils#completeProxiedInterfaces()方法获取代理目标的接口,按照规则添加一部分接口SpringProxy、Advised、DecoratingProxy

      // AopProxyUtils
      static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
         // 获取目标类实现的接口接口
         Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
         // 目标类的接口为空
         if (specifiedInterfaces.length == 0) {
            // 获取代理目标class
            Class<?> targetClass = advised.getTargetClass();
            if (targetClass != null) {
                // 判断目标类型是否是接口
               if (targetClass.isInterface()) {
                  advised.setInterfaces(targetClass);
               }
                // 代理目标类型是代理
               else if (Proxy.isProxyClass(targetClass)) {
                  advised.setInterfaces(targetClass.getInterfaces());
               }
               // 重新获取代理对象的接口集
               specifiedInterfaces = advised.getProxiedInterfaces();
            }
         }
          
         // 如果目标类未实现 SpringProxy 接口,将添加 SpringProxy 到接口集中。
         boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
         // 目标类能转换为Advised,并且未实现 Advised 接口,则添加 Advised 到接口集中
         boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
         // decoratingProxy 为true,且目标类未实现 DecoratingProxy 接口,将 DecoratingProxy 添加进接口集中
         boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
       
         // 划分接口数组长度
         int nonUserIfcCount = 0;
         if (addSpringProxy) {
            nonUserIfcCount++;
         }
         if (addAdvised) {
            nonUserIfcCount++;
         }
         if (addDecoratingProxy) {
            nonUserIfcCount++;
         }
         Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
         // 拷贝
         System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
         // 将接口class设置进对应的数组位置
         int index = specifiedInterfaces.length;
         if (addSpringProxy) {
            proxiedInterfaces[index] = SpringProxy.class;
            index++;
         }
         if (addAdvised) {
            proxiedInterfaces[index] = Advised.class;
            index++;
         }
         if (addDecoratingProxy) {
            proxiedInterfaces[index] = DecoratingProxy.class;
         }
         // 返回需要代理的接口集。
         return proxiedInterfaces;
      }	
      
    2. 执行切面和方法拦截器逻辑 ReflectiveMethodInvocation#proceed

      public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
          
          public Object proceed() throws Throwable {
              // 执行完后通知或拦截器后,将执行业务方法
      		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      			return invokeJoinpoint();
      		}
      
              // 获取通知或拦截器
      		Object interceptorOrInterceptionAdvice =
      				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
              // 通知或拦截器是 InterceptorAndDynamicMethodMatcher 
              // InterceptorAndDynamicMethodMatcher 用于将方法匹配器与拦截器结合,如果方法匹配器匹配了就是用拦截器进行调用
      		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      			InterceptorAndDynamicMethodMatcher dm =
      					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
      			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
      				return dm.interceptor.invoke(this);
      			}
      			else {
                      // 匹配失败,调用下一个匹配的拦截器
      				return proceed();
      			}
      		}
              // 调用其他拦截器,其他拦截器需要调用,因为传入了this,拦截器链可以使用引用调用本方法,以执行下一个切面或拦截器。
      		else {
      			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
      		}
      	}
      }
      
  • 相关阅读:
    解读Android 12首个开发者预览版
    Pod创建私有库
    Flutter常用网站
    Flutter常用快捷键
    多个网络请求-并发执行、顺序执行
    小猫爬山问题---贪心算法失效,深度优先搜索优化
    网络基本概念备忘:MAC地址,端口,HTTP状态码
    常见图片文件格式简析
    pdf2xls
    评分卡模型
  • 原文地址:https://www.cnblogs.com/diandiandidi/p/14667323.html
Copyright © 2011-2022 走看看