47、Spring5.x源码之旅四十七AOP代理细节二createProxy

  • 创建代理
    • AbstractAutoProxyCreator的createProxy创建代理
    • AutoProxyUtils的exposeTargetClass设置属性
    • shouldProxyTargetClass
    • ProxyProcessorSupport的evaluateProxyInterfaces
      • ProxyProcessorSupport的isConfigurationCallbackInterface
      • ProxyProcessorSupport的isInternalLanguageInterface
    • AdvisedSupport的addInterface
      • ProxyCreatorSupport的adviceChanged
    • ProxyFactory的getProxy获取代理
      • ProxyCreatorSupport的createAopProxy
        • ProxyCreatorSupport的activate
      • DefaultAopProxyFactory的createAopProxy
        • DefaultAopProxyFactory的hasNoUserSuppliedProxyInterfaces
      • JdkDynamicAopProxy的getProxy

创建代理

上篇讲了先获取匹配的通知器,其实也叫做拦截器,准备代理,这篇我们就看看是什么做的。
*

AbstractAutoProxyCreator的createProxy创建代理

进行代理工厂的创建,然后判断是否需要设置proxyTargetClass,以便于后面决定是不是要进行JDK动态代理还是CGLIB的动态代理,然后把通知器advisors包装下,加入到代理工厂,获取代理对象。

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
   
     
		//给bean定义设置暴露属性
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
   
     
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}
		// 创建代理工厂
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);//复制配置信息
		// proxyTargetClass=false的话
		if (!proxyFactory.isProxyTargetClass()) {
   
     
			if (shouldProxyTargetClass(beanClass, beanName)) {
   
     //查看是否有PRESERVE_TARGET_CLASS_ATTRIBUTE属性,有的话就要设置true
				proxyFactory.setProxyTargetClass(true);
			}
			else {
   
     
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		//构建通知器,把通用的拦截器也加进来,有些可能会要进行包装
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
   
     
			proxyFactory.setPreFiltered(true);//已经过滤处理了
		}

		return proxyFactory.getProxy(getProxyClassLoader());
	}

AutoProxyUtils的exposeTargetClass设置属性

其实就是设置他的原来的类型。

	static void exposeTargetClass(
			ConfigurableListableBeanFactory beanFactory, @Nullable String beanName, Class<?> targetClass) {
   
     

		if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
   
     
			beanFactory.getMergedBeanDefinition(beanName).setAttribute(ORIGINAL_TARGET_CLASS_ATTRIBUTE, targetClass);
		}
	}

shouldProxyTargetClass

其实就是判断他有没有PRESERVE_TARGET_CLASS_ATTRIBUTE属性,有的话就要设置ProxyTargetClass=true

	protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
   
     
		return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
				AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
	}

	public static boolean shouldProxyTargetClass(
			ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {
   
     

		if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
   
     
			BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
			return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
		}
		return false;
	}

ProxyProcessorSupport的evaluateProxyInterfaces

判断他的接口,是不是需要设置ProxyTargetClass=true,判断他的接口不是内部的回调接口和内部语言接口,就添加接口,否则就设置ProxyTargetClass=true

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;//用接口代理,也就是JDK
				break;
			}
		}
		if (hasReasonableProxyInterface) {
   
     //有接口
			// Must allow for introductions; can't just set interfaces to the target's interfaces only.
			for (Class<?> ifc : targetInterfaces) {
   
     
				proxyFactory.addInterface(ifc);
			}
		}
		else {
   
     //没接口就设置true
			proxyFactory.setProxyTargetClass(true);
		}
	}

ProxyProcessorSupport的isConfigurationCallbackInterface

是不是内部的一些接口。

	protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
   
     
		return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
				AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
	}

ProxyProcessorSupport的isInternalLanguageInterface

是不是内部语言的一些接口。

	protected boolean isInternalLanguageInterface(Class<?> ifc) {
   
     
		return (ifc.getName().equals("groovy.lang.GroovyObject") ||
				ifc.getName().endsWith(".cglib.proxy.Factory") ||
				ifc.getName().endsWith(".bytebuddy.MockAccess"));
	}

AdvisedSupport的addInterface

添加接口:

	public void addInterface(Class<?> intf) {
   
     
		Assert.notNull(intf, "Interface must not be null");
		if (!intf.isInterface()) {
   
     
			throw new IllegalArgumentException("[" + intf.getName() + "] is not an interface");
		}
		if (!this.interfaces.contains(intf)) {
   
     
			this.interfaces.add(intf);
			adviceChanged();
		}
	}

ProxyCreatorSupport的adviceChanged

添加了接口要有adviceChanged通知,不过一般我们没用到这个。

	@Override
	protected void adviceChanged() {
   
     
		super.adviceChanged();//清除缓存
		synchronized (this) {
   
     
			if (this.active) {
   
     
				for (AdvisedSupportListener listener : this.listeners) {
   
     
					listener.adviceChanged(this);
				}
			}
		}
	}

ProxyFactory的getProxy获取代理

先创建AopProxy代理,然后获取代理。

	public Object getProxy(@Nullable ClassLoader classLoader) {
   
     
		return createAopProxy().getProxy(classLoader);
	}

ProxyCreatorSupport的createAopProxy

创建AOP代理,如果激活了,就需要有激活通知,我们也也不太用到:

	protected final synchronized AopProxy createAopProxy() {
   
     
		if (!this.active) {
   
     
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

ProxyCreatorSupport的activate

激活通知,跟前面的添加接口的通知一样,都是给AdvisedSupportListener通知。:

	private void activate() {
   
     
		this.active = true;
		for (AdvisedSupportListener listener : this.listeners) {
   
     
			listener.activated(this);
		}
	}

DefaultAopProxyFactory的createAopProxy

这个才是真正创建代理,判断一些列条件,有自定义的接口的就会创建JDK代理,否则就是CGLIB

	@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.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
   
     //有接口或者是proxy类型的用JDK
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);//用CGLIB
		}
		else {
   
     
			return new JdkDynamicAopProxy(config);//用JDK
		}
	}

DefaultAopProxyFactory的hasNoUserSuppliedProxyInterfaces

这个就是说如果存在一个接口,还是SpringProxy类型的,就返回true,否则就是false,我们自定义的肯定是false,如果没接口也是false

	private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
   
     
		Class<?>[] ifcs = config.getProxiedInterfaces();
		return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
	}

JdkDynamicAopProxy的getProxy

如果是JDK的动态代理,就是我们熟悉的Proxy.newProxyInstance,不过这里调用前还做了一些处理。

	@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);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);//生成代理
	}

后面我们继续来说这个处理吧。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。