Spring源码解读8解析Aop

我们从BeanDefination到bean大体上分为这么几步
1.>原生的Bean(就是没有被处理的Bean)
2.>后置处理器的处理
3>调用Init 之类的回调方法
4>填充属性property
也就是说当一个类被实例化之后会经过后置处理器的处理
什么意思呢
>
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 我们UserService 实现了InitializingBean
    ---------------------->进行了生命周期的回调 和和@PostConstruct作用一样
    2.我自己一个类实现了BeanPostProcessor
    -------------->构造方法之后干活的
    3.构造方法自然老大啊
    在这里插入图片描述
    看清楚现象
    construct{构造}—>postProcessBeforeInitialization{后置处理器的Before}–>afterPropertiesSet{
    生命周期的回调}—>postProcessAfterInitialization{后置处理器的after}

今天就说下为什么这个顺序 以及这个和aop有什么关系

我们今天来说下registerBeanPostProcessors(beanFactory);这个方法 ,字面上的意思是注册BeanPostProcessors 何为注册就是往工厂中添加BeanPostProcessors
-------------------->我们点进去看吧
在这里插入图片描述

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
	


	找出所有实现BeanPostProcessor接口的类  从Bean工厂中
	从我们的bdmap中根据类型找出名字
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		
		//priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		//	priorityOrderedPostProcessors.remove(2);
		//internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		
		//  orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
		List<String> orderedPostProcessorNames = new ArrayList<>();
		//nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	/*	实现PriorityOrdered接口的BeanPostProcessor、
		实现Ordered接口的BeanPostProcessor、
		普通BeanPostProcessor
	* */
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				//------------add
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}
		//priorityOrderedPostProcessors.remove(1);
	

		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		
		sortPostProcessors(internalPostProcessors, beanFactory);
		//8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		//重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));


	}

beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
他的底层维护了一个集合
this.beanPostProcessors.add(beanPostProcessor);
在这里插入图片描述
他总共有7个有3个是从bdmap中获取的
剩下的都是add 的
-----------------------》
我大致说下这几个的作用吧
ApplicationContextAwareProcessor 他的功能是我们一个类如果实现了ApplicationContextAware这个接口,我们可以达到在程序运行中获取applicationContext 继而获取 Bean ,可以动态实现获取bean的信息
在这里插入图片描述
BeanPostProcessorChecker 这个的功能是 我们知道所有的实例都要经过后置处理器的处理,如果有一个实例没有经过后置处理器的处理,他就会价差并且打印出信息,
CommonAnnocationBeanPostProcessor----->这个的功能是处理公共注解 比方说生命周期的@PostConstruct
AutowiredAnnotationBeanPostProcessor 的作用是处理@Autowaired注解
RequireAnnocationBeanPostProcessor的作用 解析@Require注解的
ImportAwareBeanPostProcessor 的作用是判断一个类有没有实现ImportAware 这个接口
https://blog.csdn.net/qq_43843037/article/details/103706647
这里有这个接口的说明 redis就是这么配置的
-------------------------------------------------------------------》
我们来测试一个
RequireAnnocationBeanPostProcessor的作用 解析@Require注解的
在这里插入图片描述

比方说我们一个类里面有一个name 属性, @Required就是检查有没有给set方法赋值…
我们加了这个注解
在这里插入图片描述
启动项目报错 也就是说我们没有给Name属性赋值
------------------------------------>源码在我们手上,我们可以吧这个 RequireAnnocationBeanPostProcessor剔除掉 再测试
在这里插入图片描述
此时我们的beanPostProcessors 中就没有RequireAnnocationBeanPostProcessor他了
在这里插入图片描述
看我们此时可以打出来 构造 ,此时的@Required 这个注解就不起作用了
因为beanPostProcessors 是一个集合啊 我们直接remove() 就可以吧他剔除
-------------------------------------------------------->
Spring中7个后置处理器 有3个是先前add添加的
有3个从bdmap中得到的
后续又add了2个
-------------------------------------->
我们的aop的原理就是向Spring中添加了一个后置处理器
----------------------------------------------------------------------------------------->我又启了个项目 因为此时源码没有加入aspect的jar
在这里插入图片描述
点进来看
在这里插入图片描述
从字面上翻译 往容器中注册一个
AspectJAnnotationAutoProxyCreator 如果必要的话
实际上他是给map容器中添加了一个后置处理器
这样我们再从beanDefinationMap中取出来就不是3个了,而是4个了
在这里插入图片描述
所以
在这里插入图片描述
这个方法的就是给Spring容器中beanProcessors这个容器中加入值
正常来说是7个从bdmap中拿3个 刚开始add2个在,cglib动态代理@Configuration又add1个 然后后面又add了一个
如果加入aspectj的jar 又会加一个 并且这个是加入到bdmap中
==============================>
然后我们看下
在这里插入图片描述
看下这个方法 看下Spring的后置处理器如何工作的,换言之
AnnotationAwareAspectJAutoProxyCreator 如何把我们一个原生的Bean给变成代理类的
//------->完成Bean的实例
finishBeanFactoryInitialization
//–>实例化我们单利之前要做得事情
beanFactory.preInstantiateSingletons();
在这里插入图片描述
这个方法是把我们所有需要实例化的类拿出来 然后去实例化
------------------------------------------------>现在我们的目的就是来看我们的后置处理器在什么时候工作的 ----------------------》先跑流程 细节明天再说
在这里插入图片描述
我们卡一个断点
beanName.equalsIgnoreCase(“OrderDaoImpl”) 因为Spring要实例化的类有10个左右我们的卡成我们的
此时1 >
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
2.>mbd.isSingleton()
然后creatBean
在这里插入图片描述
然后我们看啊
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
我们通过这么一个方法返回一个代理对象
现在我们应该继续进入这一个方法看下我们这个动态代理的类什么时候初始化的
------------->换句话说,我们的后置处理器什么时候工作的
在这里插入图片描述
///–>1.BeanWrapper instanceWrapper 这个是一个Bean的包装类,何为Bean的包装, 它里面有个getWrappedInstance();方法就能把我们的Bean返回出来,我们真正的对象被这个类给包裹了

//-------------->执行这个代码就相当于执行我们的构造 这个以后再说
instanceWrapper = createBeanInstance(beanName, mbd, args)
我们通过
final Object bean = instanceWrapper.getWrappedInstance();
拿出我们的原生类
在这里插入图片描述;
看此时是原生类,也就是说此时还没有没有被后置处理器处理
----------》

在这里插入图片描述
//—>这个方法是我们用来填充属性的明天再说
populateBean(beanName, mbd, instanceWrapper);
//我们通过这个方法来实现我们的代理的 继续缩小范围
exposedObject = initializeBean(beanName, exposedObject, mbd);

在这里插入图片描述

//---------》
执行后置处理器的postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//--->执行回调方法 
invokeInitMethods(beanName, wrappedBean, mbd);
	//执行后置处理器的postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 这下知道吧刚开始的顺序
 是构造------->postProcessBeforeInitialization--->invokeInitMethods---->postProcessAfterInitialization

然后现在我们主要的看我们的Aop是在他的postProcessBeforeInitialization 工作的还是在他的postProcessAfterInitialization 里面工作的
在这里插入图片描述
看见了没 其实Spring的aop是在他的后置处理器的After 方法工作的

在这里插入图片描述
这个方法就是吧后置处理器的getBeanPostProcessors()List拿出来循环执行他的postProcessAfterInitialization 处理Bean
在这里插入图片描述
当我们的后置处理器是他的话 我们的Bean就被代理了,
我们点击去 具体去看是如何将我们的bean进行代理的
通过他的父类 AbstractAutoProxyCreator 的postProcessAfterInitialization 这个方法进行的代理
在这里插入图片描述
看见了没
wrapIfNecessary(bean, beanName, cacheKey) 通过这个方法 我们返回一个代理对象
现在我们点击进入这个方法 具体看看如何返回我们的代理对象的
在这里插入图片描述


	1. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	这个方法主要获取关于切面切点的东西  比方说获取切面,切点
	此时我们肯定需要代理啊
	-------------------->
	createProxy() 然后我们点进去看如何进行代理 
	---------------->
	这个方法看他` return proxyFactory.getProxy(getProxyClassLoader());

----------------------------------------》高能 高能
在这里插入图片描述
createAopProxy() 我们看这个方法返回AopProxy他
AopProxy是一个接口他的实现类在这里插入图片描述
也就是说如果createAopProxy() 返回的是Jdk代理对象就用Jdk动态代理
如果返回的是cglib就进行cglib代理
我们点击进去看下他用sh
在这里插入图片描述

config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)

也就是这三个有一个成立的话我们就进入
在这里插入图片描述
否则我们就进行JDK的动态代理
-------------------------------------->很可惜 我现在很菜
只知道config.isProxyTargetClass() 这个怎么配置
在这里插入图片描述
我们可以在这个注解进行赋值
@EnableAspectJAutoProxy(proxyTargetClass = )
在这里插入图片描述
他默认为false
------------------------------------------------>也就是此时他用的是
JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);

在这里插入图片描述、1. createAopProxy() 返回的对象是JdkDynamicAopProxy
2>点击进去
在这里插入图片描述
看见了没
动态代理的标准范式, this代表他实现了InvocationHandler 这个接口
在这里插入图片描述
自然讲 invoke就是他的植入逻辑
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值