spring注解开发(四)aop
aop的使用
建立目标方法类:
建立切面类 //标注这是一个切面类 @Aspect public class LogAspects { //抽取公共的切入点表达式 //1、本类引用 //2、其他的切面引用 @Pointcut("execution(public int com.spring.demo.aop.Calculator.*(..))") public void pointCut(){} //@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入) @Before("pointCut()") public void logStart(JoinPoint joinPoint){ Object[] args = joinPoint.getArgs(); System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+ Arrays.asList(args)+"}"); } @After("pointCut()") public void logEnd(JoinPoint joinPoint){ System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After"); } //JoinPoint一定要出现在参数表的第一位 @AfterReturning(value="pointCut()",returning="result") public void logReturn(JoinPoint joinPoint,Object result){ System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}"); } @AfterThrowing(value="pointCut()",throwing="exception") public void logException(JoinPoint joinPoint,Exception exception){ System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}"); } }
在配置类中将切面和目标类都配置到spring中
正常执行情况
有异常的情况下
打印了异常信息
aop原理分析
@EnableAspectJAutoProxy;注入了一个组件 AspectJAutoProxyRegistrar
AspectJAutoProxyRegistrar这个组件注册了AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator:这个组件最终是实现了
SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
最主要的就是对bean的初始化前后做了一些事情,和传递了beanFactory
程序的执行流程
刚开始传给的注解标注的类,,也就是配置类,,进行注册,然后调用 refresh();这个方法做了很多操作
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. 拦截bean的创建,注册BeanPostProcessors registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
跟踪一**册BeanPostProcessors
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. 对postProcessorNames进行归类 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. 先注册PriorityOrdered类型的BeanPostProcessors sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. 再注册Ordered类型的BeanPostProcessors 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); // Now, register all regular BeanPostProcessors. 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); // Finally, re-register all internal BeanPostProcessors. 最后注册其他的BeanPostProcessors sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
最后把BeanPostProcessor注册到BeanFactory中;
在看一下最后初始化所有非懒加载的单实例bean,也就是我们定义的bean(目标类和切面)
遍历获取容器中所有的Bean,依次创建对象
创建Bean的实例
populateBean;给bean的各种属性赋值
initializeBean:初始化bean;
1)、invokeAwareMethods():处理Aware接口的方法回调
2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
3)、invokeInitMethods();执行自定义的初始化方法
4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--》aspectJAdvisorsBuilder
* AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】 的作用:
* 1)、每一个bean创建之前,调用postProcessBeforeInstantiation();
* 关心目标类和切面类的创建
* 1)、判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
* 2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,
* 或者是否是切面(@Aspect)
* 3)、是否需要跳过
* 1)、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
* 每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
* 判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
* 2)、永远返回false
*
* 2)、创建对象
* postProcessAfterInitialization;
* return wrapIfNecessary(bean, beanName, cacheKey);//包装如果需要的情况下
* 1)、获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
* 1、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
* 2、获取到能在bean使用的增强器。
* 3、给增强器排序
* 2)、保存当前bean在advisedBeans中;
* 3)、如果当前bean需要增强,创建当前bean的代理对象;
* 1)、获取所有增强器(通知方法)
* 2)、保存到proxyFactory
* 3)、创建代理对象:Spring自动决定
* JdkDynamicAopProxy(config);jdk动态代理;
* ObjenesisCglibAopProxy(config);cglib的动态代理;
* 4)、给容器中返回当前组件使用cglib增强了的代理对象;
* 5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
*
*
* 3)、目标方法执行 ;
* 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
* 1)、CglibAopProxy.intercept();拦截目标方法的执行
* 2)、根据ProxyFactory对象获取将要执行的目标方法拦截器链;
* List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
* 1)、List<Object> interceptorList保存所有拦截器 5
* 一个默认的ExposeInvocationInterceptor 和 4个增强器;
* 2)、遍历所有的增强器,将其转为Interceptor;
* registry.getInterceptors(advisor);
* 3)、将增强器转为List<MethodInterceptor>;
* 如果是MethodInterceptor,直接加入到集合中
* 如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
* 转换完成返回MethodInterceptor数组;
*
* 3)、如果没有拦截器链,直接执行目标方法;
* 拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
* 4)、如果有拦截器链,把需要执行的目标对象,目标方法,
* 拦截器链等信息传入创建一个 CglibMethodInvocation 对象,
* 并调用 Object retVal = mi.proceed();
* 5)、拦截器链的触发过程;
* 1)、如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
* 2)、链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;
* 拦截器链的机制,保证通知方法与目标方法的执行顺序;
*
* 总结:
* 1)、 @EnableAspectJAutoProxy 开启AOP功能
* 2)、 @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
* 3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
* 4)、容器的创建流程:
* 1)、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
* 2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
* 1)、创建业务逻辑组件和切面组件
* 2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
* 3)、组件创建完之后,判断组件是否需要增强
* 是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
* 5)、执行目标方法:
* 1)、代理对象执行目标方法
* 2)、CglibAopProxy.intercept();
* 1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
* 2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
* 3)、效果:
* 正常执行:前置通知-》目标方法-》后置通知-》返回通知
* 出现异常:前置通知-》目标方法-》后置通知-》异常通知