SpringAop源码分析(基于注解)三:创建代理对象

在上篇文章SpringAop源码分析(基于注解)二:筛选通知器中,我们对AOP中通知的创建和筛选过程进行了分析,本章我们一起来看看,AOP是怎么创建代理对象的。

我们先回到Bean初始化之后,调用BeanPostProcessor后置处理器的地方。

//AbstractAutoProxyCreator.java

//在Bean初始化之后回调
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		//判断缓存中是否有
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			// 没有,为 bean 生成代理对象
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}
复制代码

wrapIfNecessary代码:

//AbstractAutoProxyCreator.java

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}

	/*
	 * 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类),或是应该跳过的类,
	 * 则不应该生成代理,此时直接返回 bean
	 */
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
<1>	// 返回匹配当前 bean 的所有的通知器  advisor、advice、interceptor
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		// 核心!创建代理对象
<2>		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}
复制代码

上篇文章我们主要分析的是<1>处代码,现在有了合适的通知器,我们要为当前Bean创建代理对象,把通知器(Advisor)所持有的通知(Advice)织入到 bean 的某些方法前后。

看代码:

//AbstractAutoProxyCreator.java

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

	//proxyTargetClass是 @EnableAspectJAutoProxy 的属性之一
	//true -> 强制使用CGLIB代理
	if (!proxyFactory.isProxyTargetClass()) {
		//false
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
			//检测 beanClass 是否实现了接口,若未实现,则将
			//proxyFactory 的成员变量 proxyTargetClass 设为 true
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}
    
        //封装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());
	}
复制代码

这里我们主要看下核心逻辑:

  • 创建代理工厂 ProxyFactory
  • 判断使用JDK还是CGLIB
  • 封装ProxyFactory
  • 创建并获取代理对象

这里的 isProxyTargetClass() 其实就是我们前面用的注解@EnableAspectJAutoProxy的属性之一,当其为true时,强制使用CGLIB代理。

下面我们接着看创建代理的代码:

//ProxyFactory.java

public Object getProxy(@Nullable ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}
复制代码

这段方法有两个方法调用:

  • createAopProxy()
    创建 AopProxy 实现类对象
  • getProxy(classLoader)
    创建代理对象

我们先来看下createAopProxy():

//DefaultAopProxyFactory.java

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	//if中的3个条件
	//1、 config.isOptimize() - 是否需要优化
	//2、 config.isProxyTargetClass() - 检测 proxyTargetClass 的值
	//3、 hasNoUserSuppliedProxyInterfaces(config) - 目标 bean 是否实现了接口
	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)) {
			//创建JdkDynamicAopProxy
			return new JdkDynamicAopProxy(config);
		}
		//创建CglibAopProxy
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		//创建JdkDynamicAopProxy
		return new JdkDynamicAopProxy(config);
	}
	}
复制代码

最终调用的是DefaultAopProxyFactory#createAopProxy(...)方法,通过这个方法创建AopProxy 的实现类,如: JdkDynamicAopProxy,然后根据这个实现类再创建代理对象。

我们以JdkDynamicAopProxy为例,看下getProxy(classLoader):

//JdkDynamicAopProxy.java

public Object getProxy() {
    return getProxy(ClassUtils.getDefaultClassLoader());
}

public Object getProxy(ClassLoader classLoader) {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
    }
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    
    // 调用 newProxyInstance 创建代理对象
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
复制代码

直接看代码最后一行,最终调用 Proxy.newProxyInstance 方法创建代理对象。

参考:
www.tianxiaobo.com/2018/06/20/…

猜你喜欢

转载自juejin.im/post/5dad10ee51882529d1528e8c