Spring 5.x Source trip forty-seven AOP proxy details of the two createProxy

Creating an agent

Part spoke first for a matching notifier, in fact, also known as interceptors, plans to represent, this is what we look to do.
Here Insert Picture Description

AbstractAutoProxyCreator create a proxy of createProxy

Created proxy factories, and then determine whether you need to set proxyTargetClassin order to decide whether to be behind the JDKdynamic proxy or CGLIBdynamic proxy, then the notifier advisorspackage, the agent added to the plant, to obtain the proxy object.

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 set the properties of exposeTargetClass

In fact, his original type setting.

	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

In fact, there is no judge his PRESERVE_TARGET_CLASS_ATTRIBUTEproperty, any necessary settings 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

Judge his interface is not need to set up ProxyTargetClass=true, judge his interface is not inside the callback interface and internal language interface, add the interface, otherwise it is set 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

Is not some internal interfaces.

	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

Some interfaces are not an internal language.

	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

Adding interfaces:

	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

Interfaces have been added adviceChangedto inform, but most of us useless to this.

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

ProxyFactory agent acquisition of getProxy

Create AopProxyproxy, and then obtain the proxy.

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

ProxyCreatorSupport的createAopProxy

Create a AOPproxy, if activated, you need to have an activation notification, we also unlikely to use:

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

Activation notice, with notice added in front of the interface, are given AdvisedSupportListenernotice. :

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

DefaultAopProxyFactory的createAopProxy

This is really creating a proxy to determine some of the conditions listed, there are custom interface will create JDKa proxy, otherwise 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

This means that if there is an interface, or the SpringProxytype of returns true, otherwise false, our custom certainly false, if the interface is not false.

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

JdkDynamicAopProxy的getProxy

If it is JDKa dynamic agency that we are familiar with Proxy.newProxyInstance, but here also made some calls before treatment.

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

Later we continue this process for it.

Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.

Published 235 original articles · won praise 74 · views 30000 +

Guess you like

Origin blog.csdn.net/wangwei19871103/article/details/105225653