基于注解的Spring-Aop原理

在容器创建完成后,会进行刷新容器(refresh()),在容器刷新时会有一步是将Bean定义保存起来
//xxxRegistrar一般是在其中手动注册一些组件,再通过@import导入到容器中;
@EnableAspectJAutoProxy
 * @Import(AspectJAutoProxyRegistrar.class)
 * 1.(beanName)internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator(组件类型)
 * 	利用AspectJAutoProxyRegistrar自定义给容器创建bean;
 * 	给容器中注册一个组件AnnotationAwareAspectJAutoProxyCreator* 2.AnnotationAwareAspectJAutoProxyCreator:
 * 
 * 
 * 		继承==>AspectJAwareAdvisorAutoProxyCreator
 * 			==>AbstractAdvisorAutoProxyCreator
 * 				==>AbstractAutoProxyCreator
 * 						implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
 * 关注后置处理器(在bean初始化前后做的工作)、自动装配BeanFactory
 * AbstractAutoProxyCreator.setBeanFactory()
 * AbstractAutoProxyCreator有后置处理器的逻辑--postProcessBeforeInstantiation--postProcessAfterInitialization
 * 
 * AbstractAdvisorAutoProxyCreator.setBeanFactory()包含-->initBeanFactory()
 * 
 * AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
 * 
 * 流程:
 * 1)、传入配置类,创建ioc容器
 * 2)、注册配置类,调用refresh()刷新容器,即是初始化容器
 * 3)、registerBeanPostProcessors(beanFactory)注册bean的后置处理器方便拦截bean的创建
 * 		1.先获取ioc容器中已经定义了的需要创建对象的BeanPostProcessor;其中有一个internalAutoProxyCreator组件,我们只是定义了BeanDefinition,还没有创建对象
 * 		2.给容器中加其他的BeanPostProcessor
 * 		3.优先注册实现了PriorityOrdered接口的处理器
 * 		4.再给容器中注册实现了Ordered接口的处理器
 * 		5.注册没有实现优先级接口的处理器
 * 		6.注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中
 * 			创建internalAutoProxyCreator的BeanPostProcessorAnnotationAwareAspectJAutoProxyCreator* 			1.创建bean的实例
 * 			2.populateBean:给bean的各种属性赋值
 * 			3.initializeBean:初始化bean【internalAutoProxyCreator】
 * 				1.invokeAwareMethods():处理Aware接口的回调,即判断bean实现了Aware接口的哪种接口	
 * 				2.applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
 * 				3.invokeInitMethods():执行自定义的初始化方法
 * 				4.applyBeanPostProcessorsAfterInitialization():应用后置处理器的postProcessAfterInitialization()
 * 
 * 			4.BeanPostProcessor[AnnotationAwareAspectJAutoProxyCreator]创建成功
 * 
 * 		7.BeanPostProcessor注册到BeanFactory中:->registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors)
 * 												->beanFactory.addBeanPostProcessor(postProcessor);
 * 	===========以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程==============
 * 	 AnnotationAwareAspectJAutoProxyCreator=>InstantiationAwareBeanPostProcessor(类型)
 * 	4)、finishBeanFactoryInitialization(beanFactory):完成BeanFactory初始化工作,创建剩下的单实例Bean
 *		1.遍历获取容器中所有的bean,依次创建对象getBean(beanName);	
 * 			getBean(beanName)=>doGetBean()=>getSingleton()=>createBean();
 * 			
 * 		2. 创建bean 
 * 			【前面知道AnnotationAwareAspectJAutoProxyCreatorInstantiationAwareBeanPostProcessor类型的】
 *AnnotationAwareAspectJAutoProxyCreator在创建bean实例之前会被拦截,InstantiationAwareBeanPostProcessor,会调用postProcessBeforeInstantiation()* 			1. 先从缓存中获取bean,如果能获取到,说明bean之前被创建过的,直接使用;否则调用createBean()创建bean实例
 *			只要创建好的bean都会被缓存起来
 *BeanPostProcessor是在bean对象创建完成初始化前后调用的】
 *InstantiationAwareBeanPostProcessor是在创建对象之前先尝试用后置处理器返回对象的】
 *				1)、后置处理器先尝试返回对象
 *					bean = applyBeanPostProcessorsBeforeInstantiation();
 *						applyBeanPostProcessorsBeforeInstantiation()中先拿到所有的后置处理器,如果是InstantiationAwareBeanPostProcessor类型的,
 *						就执行postProcessBeforeInstantiation():会在下章1.1详细讲到
 *					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
 * 			2. createBean():创建bean->AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean的实例
 * 				1. resolveBeforeInstantiation():解析BeforeInstantiation
 * 					希望后置处理器能够在此返回一个代理对象,如果能返回就返回,如果不能就继续
 * 				2. doCreateBean(beanName, mbdToUse, args);真正创建一个bean实例;和3.6流程一样
 * 	【会循环的验证并创建bean,所以会重复的执行语句】
 * 		AnnotationAwareAspectJAutoProxyCreatorInstantiationAwareBeanPostProcessor】的作用:
 *			1)、	在每个bean创建之前,会调用postProcessBeforeInstantiation()
 *				关注在Aspect配置类中的AspectServiceControllerAspect的创建过程:
 *				1)、判断当前bean是否在advisedBeans中(保存了所有需要增强的bean:注解有before...* 				2)、判断当前bean是否是基础类型的AdvicePointcutAdvisorAopInfrastructureBean* 					或者是不是切面(@Aspect)
 * 				3)、是否需要跳过
 * 					1.获取候选的增强器(切面里的增强方法)【List<Advisor> candidateAdvisors】
 * 					advisor类型都是InstantiationModelAwarePointcutAdvisor
 * 					2.始终返回的是false
 * 			2)、	创建对象
 * 			postProcessAfterInitialization		
 * 				1)、	return wrapIfNecessary(bean, beanName, cacheKey)//包装,如果需要的话
 * 					1.获取候选的所有增强器(通知方法) :Object[] specificInterceptors;
 * 						getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
 * 						找到能在当前bean使用的增强器(找哪些通知方法是需要切入当前bean方法的)
 * 					2.获取bean可用的;findAdvisorsThatCanApply()
 * 					3.给增强器排序;sortAdvisors()
 * 				2)、把增强器添加到缓存中
 * 				3)、如果当前bean需要增强,创建bean的代理对象;createProxy()
 *  				1.获取所有的增强器(通知方法)
 *  				2.保存到proxyFactory中<--config
 *  				3.创建代理对象 spring自动决定
 *  					JdkDynamicAopProxy(config)Jdk的自动代理(当类实现接口时,选择jdk自动代理)
 *  					ObjenesisCglibAopProxy(config)Cglib的自动代理(当类没有实现接口时,选择Cglib代理)
 *  			4)、给容器中返回使用cglib增强了的代理对象	
 * 				5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法时,代理对象就会执行通知方法的流程
 * 			3)、目标方法的执行(div())
 * 				容器中保存了组件的代理对象(Cglib增强后代理对象),这个代理对象中保存了详细信息(比如增强器、对象方法、xxx)
 *				1)、CglibAopProxy.intercept();拦截目标方法的执行
 *				2)、根据proxyFactory获取将要执行的方法的拦截器链
 *					List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)
 * 						1.List<Object> interceptorList保存所有的拦截器 List长度为5
 * 							一个默认的ExposeInvocationInterceptor4个增强器
 * 						2.遍历所有的增强器,将其封装成intercetpor:-->registry.getInterceptors(advisor);
 * 						3.将增强器转为List<MethodInterceptor>;
 * 							如果增强器是MethodInterceptor,直接加入到集合中
 * 							如果不是,用AdvisorAdapter将增强器转为MethodInterceptor
 * 							转换完成返回MethodInterceptor数组
 * 				3)、如果没有拦截器链,直接执行目标方法
 * 					 拦截器链(每一个通知方法被包装成方法拦截器,后来方法执行是利用MethodInterceptor机制)
 * 				4)、如果有拦截器链,把需要执行的目标方法、目标对象、拦截器链等信息传入创建一个CglibMethodInvocation对象,
 * 					并调用Object retVal = mi.proceed()
 * 				5)、拦截器链的触发过程	
 * 					1.如果没有拦截器执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
 * 					2.链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
 * 						拦截器链的机制,保证通知方法与目标方法的执行顺序(注解积累)

在这里插入图片描述
总结:
在这里插入图片描述
**类的初始化:**是完成程序执行前的准备工作。在这个阶段,静态的(变量,方法,代码块)会被执行。同时在会开辟一块存储空间用来存放静态的数据。初始化只在类加载的时候执行一次。
类的实例化:是指创建一个对象的过程。这个过程中会在堆中开辟内存,将一些非静态的方法,变量存放在里面。在程序执行的过程中,可以创建多个对象,既多次实例化。每次实例化都会开辟一块新的内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值