(13)spring注解学习之AOP原理--AnnotationAwareAspectJAutoProxyCreator的拦截过程

AnnotationAwareAspectJAutoProxyCreator做了什么?

AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBeanPostProcessor
finishBeanFactoryInitialization操作之前AnnotationAwareAspectJAutoProxyCreator 把部分有beanDefinition的bean的实例 已经全部注册到容器中,现在初始化其他bean实例

refresh()

完成BeanFactory初始化工作;创建剩下的单实例bean
在这里插入图片描述

1.完成BeanFactory初始化工作finishBeanFactoryInitialization(beanFactory)

/**
 * Finish the initialization of this context's bean factory,
 * initializing all remaining singleton beans.
 */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}
1.1 preInstantiateSingletons()
  • 遍历获取容器中所有的Bean,依次创建对象 =》getBean(beanName)
@Override
public void preInstantiateSingletons() throws BeansException {
	// Trigger initialization of all non-lazy singleton beans...
	
	//遍历获取容器中所有的Bean
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
				//xxxxxx省略
			}else {
				// 创建对象
				getBean(beanName);
			}
		}
	}
}
  • getBean->doGetBean()->getSingleton()-> singletonFactory.getObject()->createBean()
  1. doGetBean() 先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则初次生成该bean,容器中之前无该bean,所以会新重建该bean
  • 只要创建好的Bean都会被缓存起来
    在这里插入图片描述
  • createBean()
    在这里插入图片描述

2. 创建bean

AnnotationAwareAspectJAutoProxyCreator 因为继承了InstantiationAwareBeanPostProcessor接口,所以会在所有bean创建之前会有一个拦截,先尝试返回bean的实例,调用postProcessBeforeInstantiation()

2.1 bean创建之前拦截
protected Object createBean()
{
    // 先尝试通过 后置处理器返回 代理对象
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

    //不能返回 代理对象就创建 bean实例
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);

}
2.1.1 resolveBeforeInstantiation ==》解析BeforeInstantiation
  • 希望后置处理器在此能返回一个代理对象;
  • 如果能返回代理对象就使用,如果不能就doCreateBean()
    在这里插入图片描述
2.1.2 resolveBeforeInstantiation里面的后置处理器先尝试返回对象

在这里插入图片描述

2.1.3 applyBeanPostProcessorsBeforeInstantiation
  • 拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor【相当于AnnotationAwareAspectJAutoProxyCreator 】
  • 就执行postProcessBeforeInstantiation
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
	}
	return null;
}
2.1.4 postProcessBeforeInstantiation
  • 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
  • 判断当前bean是否是基础类型的,是否实现了Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
  • 是否需要跳过
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
	Object cacheKey = getCacheKey(beanClass, beanName);

	if (beanName == null || !this.targetSourcedBeans.contains(beanName)) 
	{
		// 先判断这个beanName 是否在advisedBeans增强器中
		if (this.advisedBeans.containsKey(cacheKey)) {
			return null;
		}
		//判断当前bean是否是基础类型的
		if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return null;
		}
	}

		// Create proxy here if we have a custom TargetSource.
		if (beanName != null) {
			TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
			if (targetSource != null) {
				this.targetSourcedBeans.add(beanName);
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
				Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
				this.proxyTypes.put(cacheKey, proxy.getClass());
				return proxy;
			}
		}

		return null;
	}
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {

	return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
}
  • 是否需要跳过
  • 1)、获取候选的增强器(切面里面的通知方法)【List candidateAdvisors】
  •  每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
    
  •  判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;是就返回true
    
  • 2)、父类的super.shouldSkip(beanClass, beanName) 永远返回false–跳过
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	// TODO: Consider optimization by caching the list of the aspect names
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	for (Advisor advisor : candidateAdvisors) {
		if (advisor instanceof AspectJPointcutAdvisor) {
			if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
				return true;
			}
		}
	}
	return super.shouldSkip(beanClass, beanName);
}

增强方法:
在这里插入图片描述

2.2 创建bean

doCreateBean(beanName, mbdToUse, args)

2.3 初始化bean

populateBean(beanName, mbd, instanceWrapper);
initializeBean()
{
  	applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  	// 执行自定义初始化
  	invokeInitMethods(beanName, wrappedBean, mbd);
  	applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

2.4 初始化bean之后的后置处理器执行

applyBeanPostProcessorsAfterInitialization
-----> postProcessAfterInitialization

2.4.1 postProcessAfterInitialization

//如果需要的情况下包装
return wrapIfNecessary(bean, beanName, cacheKey)

@Override
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;
}
2.4.2 获取当前bean的所有增强器(通知方法) getAdvicesAndAdvisorsForBean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) 
{
	// Create proxy if we have advice.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		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;
}
  • getAdvicesAndAdvisorsForBean —获取当前bean的所有增强器
@Override
	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
  • findEligibleAdvisors—获取到能在当前bean使用的增强器。
/*
* @see #findCandidateAdvisors
 * @see #sortAdvisors
 * @see #extendAdvisors
 */
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;
}
  • 1)找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
    比如说这个给 MathCalculator定义的四个增强方法(@Before/ @After / @AfterReturning/ @AfterThrowing)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
  • 2)获取到能在当前bean使用的增强器
    四个增强方法(@Before/ @After / @AfterReturning/ @AfterThrowing)在当前bean的方法名字
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  • 3)给增强器排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
2.4.3 保存当前bean在advisedBeans中:表明当前bean是增强bean
this.advisedBeans.put(cacheKey, Boolean.TRUE);
2.4.4 如果当前bean需要增强,创建当前bean的代理对象createProxy()方法
Object proxy = createProxy(
			bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
			
		ProxyFactory proxyFactory = new 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());
}
  • 1)、获取所有增强器(通知方法)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  • 2)、保存到代理工厂 proxyFactory
proxyFactory.addAdvisors(advisors);
  • 3)、创建代理对象 proxyFactory.getProxy(getProxyClassLoader())
public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
}
  • Spring自动决定创建那种代理对象
    <1>.JdkDynamicAopProxy(config);jdk动态代理; <2>.ObjenesisCglibAopProxy(config);cglib的动态代理;

新建一个AOP代理对象:getProxy()本质上就是创建AOP代理:createAopProxy

protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
}

targetClass 当前就是 MathCalculator类

如果 targetClass 是实现接口的,就用JdkDynamicAopProxy

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
		Class<?> targetClass = config.getTargetClass();
		
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}
2.4.5 给容器中返回当前组件使用cglib增强了的代理对象

createProxy () 方法返回的代理对象
在这里插入图片描述

2.4.6 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值