Spring源码阅读-AOP实现核心类AbstractAutoProxyCreator
Spring源码阅读-AOP实现核心类AbstractAutoProxyCreator
Small-Liu 发表于4个月前
Spring源码阅读-AOP实现核心类AbstractAutoProxyCreator
  • 发表于 4个月前
  • 阅读 80
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

前面两篇主要是讲从两个入口对AbstractAutoProxyCreator的子类进行注册,下面看具体实现逻辑:

一、先看类图,找到AbstractAutoProxyCreator在spring所处的位置:

索引AbstractAutoProxyCreator的本质是BeanPostProcessor,AbstractAutoProxyCreator中实现了代理创建的逻辑,它的子类AbstractAdvisorAutoProxyCreator主要是获取Advisors, 核心方法getAdvicesAndAdvisorsForBean,而图中红色字实现类就是前面两篇分别讲的注册,他们有一些根据自己场景的实现逻辑。

二、debug代码,跟踪流程:

在createBean中,doCreateBean是真正创建对象的地方,在创建对象之前调用了postProcessBeforeInstantiation方法,给扩展点一次创建代理的机会,如果代理对象返回不为空则createBean就直接返回了,后面的目标对象就不再实例化了。

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
	Object cacheKey = getCacheKey(beanClass, beanName);

	if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
		if (this.advisedBeans.containsKey(cacheKey)) {
			return null;
		}
		// 1. 有些对象是不可以被代理的,基类:Advices, Advisors and AopInfrastructureBeans; 带有aop注解类: @Aspect
		// 2. 子类可以复写该类,如果一些情况不需要被代理, shouldSkip返回true
		if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return null;
		}
	}

	// Create proxy here if we have a custom TargetSource.
	// Suppresses unnecessary default instantiation of the target bean:
	// The TargetSource will handle target instances in a custom fashion.
	if (beanName != null) {
		//获取targetSource, 如果存在则直接在对象初始化之前进行创建代理, 避免了目标对象不必要的实例化
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		
		//如果有自定义targetSource就要这里创建代理对象
		//这样做的好处是被代理的对象可以动态改变,而不是值针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象)
		if (targetSource != null) {
			this.targetSourcedBeans.add(beanName);
			//获取Advisors, 这个是交给子类实现的
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			//返回代理的对象
			return proxy;
		}
	}

	return null;
}

postProcessBeforeInstantiation中如果获取到自定义的TargetSource则直接创建代理对象,创建代理对象之前先调用getAdvicesAndAdvisorsForBean获取拦截对象Advisors,然后调用createProxy创建代理对象。

如果没有自定义TargetSource,则走到postProcessAfterInitialization方法创建代理,逻辑跟上面一样,唯一不同的是创建了个默认的TargetSource (SingletonTargetSource),如下:

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			//如果没有被代理过则代理
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	//targetSourcedBeans包含,说明前面创建过
	if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	//跟前面同样的判断
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	// 获取advisor, 寻找Advisors,过滤,并做排序
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		//这边跟前面创建代理对象一样,只是默认用SingletonTargetSource
		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;
}

三、createProxy

这里比较重要的两点:1. 怎么获取Advisor的,2. 怎么创建代理对象的,这边先看怎么创建代理对象的,下面是createProxy的实现逻辑:

protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors,
		TargetSource targetSource) {

	//创建代理的工作交给ProxyFactory
	ProxyFactory proxyFactory = new ProxyFactory();
	// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
	
	// 把配置copy过来, 这些配置后面用到时会看到具体意义
	proxyFactory.copyFrom(this);

	//根据一些情况判断是否要设置proxyTargetClass=true
	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		} else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

	// 把指定和通用拦截对象合并, 并都适配成Advisor
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	for (Advisor advisor : advisors) {
		proxyFactory.addAdvisor(advisor);
	}
	//设置参数
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);
	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	//上面准备做完就开始创建代理
	return proxyFactory.getProxy(this.proxyClassLoader);
}

接着跟进到ProxyFactory中:

public class ProxyFactory extends ProxyCreatorSupport {

	public Object getProxy(ClassLoader classLoader) {
		//用ProxyFactory创建AopProxy, 然后用AopProxy创建Proxy, 所以这里重要的是看获取的AopProxy对象是什么, 
		// 然后进去看怎么创建动态代理, 提供了两种:jdk proxy, cglib
		return createAopProxy().getProxy(classLoader);
	}
}

public class ProxyCreatorSupport extends AdvisedSupport {
	private AopProxyFactory aopProxyFactory;
	
	public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
	
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		//先获取创建AopProxy的工厂, 再由此创建AopProxy
		return getAopProxyFactory().createAopProxy(this);
	}
	
	public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}
}

流程就是用AopProxyFactory创建AopProxy, 再用AopProxy创建代理对象,这里的AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy方法:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

	@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()) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		} else {
			return new JdkDynamicAopProxy(config);
		}
	}

	/**
	 * Determine whether the supplied {@link AdvisedSupport} has only the
	 * {@link org.springframework.aop.SpringProxy} interface specified (or no
	 * proxy interfaces specified at all).
	 */
	private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
		Class<?>[] interfaces = config.getProxiedInterfaces();
		return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class.equals(interfaces[0])));
	}
}

这里就是决定创建代理对象是用jdk proxy,还是用cglib了,最简单的从使用方面使用来说:设置proxyTargetClass=true强制使用cglib代理,什么参数都不设并且对象类实现了接口则默认用jdk代理,如果没有实现接口则也必须用cglib。后面分两步:1 创建代理对象,2 调用目标对象方法,代理类会找到匹配的Advisors进行拦截,JdkDynamicAopProxy和ObjenesisCglibAopProxy里面逻辑描述起来有一定的篇幅,要单独分析。

四、Advisor获取

Advisor是由子类AbstractAdvisorAutoProxyCreator实现,入口方法getAdvicesAndAdvisorsForBean:

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
		//寻找Advisors,过滤,并做排序
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//寻找候选集
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		//对候选集进行过滤
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		//扩展, 交由子类实现
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			//排序
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

	protected List<Advisor> findCandidateAdvisors() {
		//里面是从beanFactory获取所有Advisor接口类型的对象
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}
}

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		//调用父类,首先获取实现了Advisor接口的对象
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		// 其次获取AspectJ注解修饰的
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		return advisors;
	}
}

主要根据两种情况获取Advisor,1:实现了Advisor接口,2:被@Aspect注解修饰的转成Advisor。

 

上面主要看的是总体,具体内部还有很多细节需要深究,比如:@Aspect修饰的是怎么转成Advisor的;代理对象是怎么调用的等。

 

 

标签: Spring aop
共有 人打赏支持
粉丝 13
博文 56
码字总数 49976
×
Small-Liu
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: