AOP

实现方式

@EnableAspectJAutoProxy开启基于注解的AOP功能
@Aspect注解标注切面
@before @after
三步:

  1. 将业务逻辑喝切面类加入容器,告诉spring哪个是切面类@Aspect @Pointcut(“execution(public …)”)切入点表达式
  2. 切面类的每一个方法上标注通知注解,告诉spring何时运行
  3. 开启@EnableAspectJAutoProxy

源码原理

AOP[查看给容器中注入了什么组件,组件什么时候工作,组件的功能]
@EnableAspectJAutoProxy
通过AspectJAutoProxyRegistrar给容器注册了一个
AnnotationAwareAspectJAutoProxyCreator最终继承(SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware)关注最终继承的后置处理器、自动装配BeanFactory

抽象的父类AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.有后置处理器

AbstractAdvisorAutoProxyCreator.setBeanFactory()重写了 调用->initBeanFactory()

AnnotationAwareAbstractAutoProxyCreator.initBeanFactory()重写了

容器启动流程

1.传入配置类,创建容器
2.注册配置类,refresh方法刷新容器
3.registerBeanPostProcessors(beanFactory),注册bean后置处理器方便拦截bean的创建
1)拿到当前已有的后置处理器BeanPostProcessor
2)新增BeanPostProcessor
3)先后按实现接口的优先级先后注册
4)注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器里
bean实例创建流程
5. beanFactory.addBeanPostProcessor(postProcessor)
…AnnotationAwareAspectJAutoProxyCreator创建和注册完成
AnnotationAwareAspectJAutoProxyCreator==》InstantiationAwareBeanPostProcessor
4.finishBeanFactoryInitialization(beanFactory);完成beanFactory初始化,创建剩下的bean,
1)遍历容器中所有的bean,getBean(beanName)
getBean->doGenBean->getSingleton
2) 创建bean,先在缓存中查询,不存在则创建
createBean();
【BeanPostProcessor是创建bean对象前后调用;而InstantiationAwareBeanPostProcessor是在创建bean实例之前先尝试用后置处理器返回对象】
1)、resolveBeforeInstantiation(beanName,mbdToUse),解析BeforeInstantiation
希望后置处理器再次能返回一个代理对象,如果能返回代理就使用,否则继续
1:后置处理器尝试返回对象,拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor,就执行postProcessBeforeInstantiation
2)、doCreateBean(beanName,mbdToUse,args);真正的创建一个bean实例,与3.4一样

AnnotationAwareAspectJAutoProxyCreator==》InstantiationAwareBeanPostProcessor作用
1.在bean创建之前执行postProcessBeforeInstantiation
1)判断当前bean是否在advisedBeans中(保存了所有需要增强的bean(需要切面))
2)判断当前bean是不是基础类型(也是为了判断切面)或者是否切面
3)是否要跳过(查看是否有增强器,切面方法)
2.创建对象
postProcessAfterInitialization return wrapIfNecessary(bean, beanName, cacheKey);
1)获取当前bean的候选增强器(通知方法)找哪些通知方法是要切人当前bean方法的
2)找到当前bean能用的增强器
3)排序
2.保存当前bean在adviseBeans中,
3.如果当前bean需要增强,创建当前bean的代理对象
1)获取所有增强器(通知方法)
2)保存ProxyFactory
3)创建代理对象,spring决定
JDK动态代理(实现了接口的)或者cglib动态代理(未实现接口,或者指定),
4.返回当前组件cglib增强后的代理对象
5.以后容器中获取到的就是这个代理对象

3.目标方法执行:
容器中保存了组件的代理对象(cglib增强的对象),这个对象里面保存的详细信息(增强器,目标对象等)
1)CglibAopProxy.intercept();拦截目标方法的执行
2)根据proxyFactory获取将要执行的方法的拦截器链,如何获取
interceptorList保存拦截器(5个),一个默认的ExposeInvocationInterceptor和4个增强器
遍历增强器,转为Interceptor
3)如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建
CglibMethodInvocation对象,并调用Object retVal = mi.proceed();
拦截器链chain(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
4)拦截器链的触发过程:链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再执行

总结

1.@EnableAspectJAutoProxy开启AOP功能
2.@EnableAspectJAutoProxy会给容器注册一个组件AnnotationAwareAspectJAutoProxyCreator
3.AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
4.容器的创建流程
1)registerBeanPostProcessors注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator
2)finishBeanFactoryInitialization初始化剩下的单实例bean
1)、创建业务逻辑组件和切面组件
2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
3)、组件创建完成后,判断组件是否需要增强
是:切面的通知方法,包装成增强(Advisor);给业务逻辑组件创建一个代理对象
5.执行目标方法
1)代理对象的执行目标方法
2)CglibAopProxy.intercept()
1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
3)、效果
正常执行:前置通知-》目标方法-》后置通知-》返回通知
出现异常:前置通知-》目标方法-》后置通知-》异常通知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值