Spring5 源码阅读笔记(3)AOP 入口:AbstractAutoProxyCreator

名词介绍

  • JoinPoint:需要增强的方法
  • PointCut:能够被一个正则表达式匹配到的一组JoinPoint
  • Advice:增强方法
  • Aspect/Advisor:PointCut + Advice
  • Proxy:代理,方法被增强的类

类结构图

在这里插入图片描述
在这里插入图片描述

基于注解开启AOP

@Component
/*
* 开启注解AOP
* 替代了:<aop:aspectj-autoproxy/>
* */
@EnableAspectJAutoProxy(proxyTargetClass = false,exposeProxy = true)
public class EnableAspectJAutoProxyBean {
}

跟源码

Spring5 源码阅读笔记(1.4.2.5)initializeBean(beanName, exposedObject, mbd) 中有一个方法 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),跟进去

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

跟 postProcessAfterInitialization:
在这里插入图片描述
这个 AbstractAutoProxyCreator 就是用来处理AOP的。跟进去:

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

跟 wrapIfNecessary:

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;
	}
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	//重要程度:5 创建当前bean的代理,如果这个bean有advice的话 见3.1
	// Create proxy if we have advice.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	//如果有切面,则生成该bean的代理
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		//把被代理对象bean实例封装到SingletonTargetSource对象中 见3.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;
}
发布了144 篇原创文章 · 获赞 250 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44367006/article/details/104544332