AnnotationAwareAsepctJAutoProxyCretor调用的是【InstantiationAwareBeanPostProcessor】后置处理器
作用 1.每个Bean在创建之前都要调用postProcessBeforeInstantiation方法
先判断当前Bean是否在advisedBeans中(保存了所有需要增强Bean)需要切面业务逻辑
2.判断当前Bean是不是基础类型的或者是不是有标注@Aspect的切面注解
boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
3.是否需要跳过this.shouldSkip(beanClass, beanName))
3.1获取候选的增强器《切面里面的通知方法》
List<Advisor> candidateAdvisors = this.findCandidateAdvisors(); Iterator var4 = candidateAdvisors.iterator();
如果增强器是AspectJPointcutAdvisor类型则会返回true
4.创建对象postProcessAfterInitialization
if (!this.earlyProxyReferences.contains(cacheKey)) { return this.wrapIfNecessary(bean, beanName, cacheKey); }
4.1获取当前Bean的所有增强器(通知方法)specificInterceptors
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
4.2找到能在当前能应用的增强器(找到哪些方法可以切入到当前Bean的方法)
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
有标注过@Before一些切面注解的话,就会被存到eligibleAdvisors 下,当做可以使用的方法
if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = this.sortAdvisors(eligibleAdvisors); }
在给它们排序一下,毕竟@Before是在前面,假如你顺序不一样,执行的还是@Before
保存当前Bean在advisedBeans中
this.advisedBeans.put(cacheKey, Boolean.TRUE);
4.3创建代理对象
如果当前Bean需要增强,就需要创建代理对象
4.4获得所有增强器,保存到通知方法proxyFactory
4.5 创建代理对象
JdkDynamicAopProxy(Config)jdk动态代理
ObjensisCglibAopProxy(Config)cglib代理
给容器返回到cglib代理对象
我们可以发现容器中保存了组件的对象(cglib增强后的对象)
5.1然后我们进入到cglib.intercept方法中
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Class<?> targetClass = null; Object target = null;
5.2根据ProxyFactory获取目标方法的拦截器(div)
5.2.1保存所有的拦截器List<Object> interceptorList = new ArrayList(config.getAdvisors().length);
里面有一个默认的增强器,还有四个以@Before,@After,@Returnning,@ReturnningException增强器方法
5.2.2遍历所有的增强器,将其转换成interceptors
5.2.3将增强器转换为List<MethodInterceptor> interceptors
如果是interceptors则直接添加到
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor)advice); }
如果不是interceptors则先创建一个迭代器
Iterator var4 = this.adapters.iterator(); while(var4.hasNext()) { AdvisorAdapter adapter = (AdvisorAdapter)var4.next(); if (adapter.supportsAdvice(advice)) { interceptors.add(adapter.getInterceptor(advisor)); }
转换完成返回
return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
我们发现AfterReturnning和Before都被封装过
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
5.3如果没有拦截器链,直接执行目标方法
拦截器链(每一个方法都被包装成拦截器。利用MethodInterceptor机制)
如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链所有信息创建一CglibMethodInvocation对象并调用proceed方法
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
5.4拦截器链的触发过程
retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
我们将转换完成的方法,执行new CglibAopProxy.proceed方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
currentInterceptorIndex记录当前拦截器的索引
5.1如果没有执行拦截器目标方法,或者拦截器的索引和拦截器数组大小-1相同
5.2 通过 else { Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
++导致每次索引会多一,会遍历完所有拦截器
六——拦截器调用所有通知
当我们的拦截器通知达到5的时候 ,立马会调用我们的前置通知
当索引和拦截器一样长的时候则会进入invokeJoinpoint方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
这里的做法就是数据结构的压栈(栈的插入)根据先进后出的方法,依次调用倒数第二个进,倒数第三个进,最后得出所有方法
具体流程图如下