Spring5 源码阅读笔记(3.2)createProxy 创建代理

本文深入探讨了Spring框架中AOP代理的创建过程,包括AbstractAutoProxyCreator类的createProxy方法如何根据目标对象类型选择合适的代理方式,以及如何通过ProxyFactory构建代理实例。详细分析了从Interceptors到Advisor的转换过程,以及JDK动态代理和CGLIB代理的选择机制。
部署运行你感兴趣的模型镜像

跟代码

类 AbstractAutoProxyCreator

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

	/**
	 * isProxyTargetClass()
	 *
	 * true
	 * 1、目标对象实现了接口 – 使用CGLIB代理机制
	 * 2、目标对象没有接口(只有实现类) – 使用CGLIB代理机制
	 *
	 * false
	 * 1、目标对象实现了接口 – 使用JDK代理机制(代理所有实现了的接口)
	 * 2、目标对象没有接口(只有实现类) – 使用CGLIB代理机制
	 *
	 *默认false
	 */
	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			//proxyTargetClass 是否对类进行代理,而不是对接口进行代理,设置为true时,使用CGLib代理。
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

	//把advice类型的增强包装成advisor切面 见下3.2.1
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	//所有的切面
	proxyFactory.addAdvisors(advisors);
	//封装的bean实例
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	////用来控制代理工厂被配置后,是否还允许修改代理的配置,默认为false
	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}

	//获取代理实例 见3.2.2
	return proxyFactory.getProxy(getProxyClassLoader());
}

3.2.1 buildAdvisors

在这里插入图片描述

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
	// Handle prototypes correctly...
	//自定义MethodInterceptor,包装成Advisor
	Advisor[] commonInterceptors = resolveInterceptorNames();

	List<Object> allInterceptors = new ArrayList<>();
	if (specificInterceptors != null) {
		//把切面的Interceptors放进来
		allInterceptors.addAll(Arrays.asList(specificInterceptors));
		//把自定义的Interceptors放进来
		if (commonInterceptors.length > 0) {
			if (this.applyCommonInterceptorsFirst) {
				allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
			}
			else {
				allInterceptors.addAll(Arrays.asList(commonInterceptors));
			}
		}
	}
	if (logger.isTraceEnabled()) {
		int nrOfCommonInterceptors = commonInterceptors.length;
		int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
		logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
				" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
	}

	Advisor[] advisors = new Advisor[allInterceptors.size()];
	for (int i = 0; i < allInterceptors.size(); i++) {
		//包装成advisor对象
		advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
	}
	return advisors;
}

跟 wrap:
类 DefaultAdvisorAdapterRegistry

@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
	if (adviceObject instanceof Advisor) {
		return (Advisor) adviceObject;
	}
	if (!(adviceObject instanceof Advice)) {
		throw new UnknownAdviceTypeException(adviceObject);
	}
	Advice advice = (Advice) adviceObject;
	if (advice instanceof MethodInterceptor) {
		//匹配所有方法
		return new DefaultPointcutAdvisor(advice);
	}
	for (AdvisorAdapter adapter : this.adapters) {
		// Check that it is supported.
		if (adapter.supportsAdvice(advice)) {
			return new DefaultPointcutAdvisor(advice);
		}
	}
	throw new UnknownAdviceTypeException(advice);
}

3.2.2 getProxy

类 proxyFactory

public Object getProxy(@Nullable ClassLoader classLoader) {
	//根据目标对象是否有接口来判断采用什么代理方式,cglib代理还是jdk动态代理
	return createAopProxy().getProxy(classLoader);
}

跟 getProxy:
类 AopProxy
在这里插入图片描述
选 JDKDynamicAopProxy
在这里插入图片描述

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isTraceEnabled()) {
		logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
	}
	//advised是代理工厂对象
	Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
				//熟悉的方法
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值