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

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

咱们先回到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代码:ide

//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 的某些方法先后。源码分析

看代码:post

//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代理。ui

下面咱们接着看建立代理的代码:this

//ProxyFactory.java

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

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

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

咱们先来看下createAopProxy():spa

//DefaultAopProxyFactory.java

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	//if中的3个条件
	//一、 config.isOptimize() - 是否须要优化
	//二、 config.isProxyTargetClass() - 检测 proxyTargetClass 的值
	//三、 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/…

相关文章
相关标签/搜索