2023-09-16
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105225653

创建代理

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

202309162317499891.png

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);//生成代理
    	}

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

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

阅读全文