springAOP流程(spring5.x源码解析)

1、准备工作

1.1 首先导入maven依赖
	<dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.2</version>
    </dependency>
1.2 添加一个配置类,使用@EnableAspectJAutoProxy注解开启aop功能
 	@Configuration
 	@ComponentScan("test.springaop")
 	@EnableAspectJAutoProxy()
	public class AppConfig {
	}
1.3 创建一个切面类,并定义四种通知(注意,@Aspect注解是定义此类为切面类,必须加这个注解)
 	@Component
	@Aspect
	public class MyAspect {
		//切点
		@Pointcut("execution(* test.springaop.HomeDao.home())")
		private void pointCut(){}
		//前置通知
		@Before("pointCut()")
		public void beforeCut(){
		  System.out.println("before....");
		}
		//后置通知
		@After("pointCut()")
		public void afterCut(){
		  System.out.println("after...."); 
		}
		//返回通知
		@AfterReturning("pointCut()")
		public void afterReturningCut(){
		  System.out.println("afterReturning....");
		}
		//异常通知
		@AfterThrowing("pointCut()")
		public void afterThrowingCut(){
			System.out.println("afterThrowing....");
		}
	}
1.4 定义一个HomeDao,并定义home方法作为被切入的方法,将其加入到spring容器中
@Component
public class HomeDao{
	@Override
	public void home(){
    	System.out.println("假装查询数据库");
    }
}
1.5 添加一个测试类,初始化spring上下文环境,并调用homeDao的home方法
public class Test {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(AppConfig.class);
    	HomeDao homeDao= (HomeDao) ac.getBean("homeDao");
   	    homeDao.home();
	}
}

2、研究aop源码

2.1 首先点进@EnableAspectJAutoProxy注解中
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}
可以看到这个注解中使用@Import注解,这个注解是向容器中导入某些类,而此时是向容器中导入了一个AspectJAutoProxyRegistrar类
2.2 点进AspectJAutoProxyRegistrar类中
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
    if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
        AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
    }

    if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
        AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
    }

 }
}
这个类实现了ImportBeanDefinitionRegistrar 这个类,而ImportBeanDefinitionRegistrar类的作用是向spring容器中注入类的,而AspectJAutoProxyRegistrar这个类到底向容器中注入了什么类呢?
我们可以看到registerBeanDefinitions方法中有一行代码AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);顾名思义向容器中注册AspectJAnnotationAutoProxyCreator如果有需要的话。我们点进这个方法中
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
再点进去
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
再点进去
 private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
        BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }

        return null;
    } else {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", -2147483648);
        beanDefinition.setRole(2);
        registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
        return beanDefinition;
    }
}
此时我们可以看到真正的逻辑了,首先他先判断容器中是否已经有一个叫internalAutoProxyCreator的类,我们第一次肯定没有,所以走到else,在else中他先new了一个RootBeanDefinition(cls),而这个cls就是上面传过来的AnnotationAwareAspectJAutoProxyCreator类,然后设置了一些参数,最终将这个bean定义注册到spring容器中并返回。由此可见就是注册了AnnotationAwareAspectJAutoProxyCreator这个类,而这个类的名称为internalAutoProxyCreator
2.3 接下来我们就要开始研究AnnotationAwareAspectJAutoProxyCreator这个类是怎么创建出来的呢?
通过点进去观察,我们可以发现这个类继承关系为AnnotationAwareAspectJAutoProxyCreator—>AspectJAwareAdvisorAutoProxyCreator—>AbstractAdvisorAutoProxyCreator—>AbstractAutoProxyCreator在容器启动时,首先会调用AnnotationConfigApplicationContext类的refresh方法,然后调用this.registerBeanPostProcessors(beanFactory);方法,这个方法就是向容器中注册所有的后置处理器(实现了BeanPostProcessor类的类),用来拦截bean的创建过程。我们通过点进去方法定位到PostProcessorRegistrationDelegate的registerBeanPostProcessors方法
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList();
    List<String> orderedPostProcessorNames = new ArrayList();
    List<String> nonOrderedPostProcessorNames = new ArrayList();
    String[] var8 = postProcessorNames;
    int var9 = postProcessorNames.length;

    String ppName;
    BeanPostProcessor pp;
    for(int var10 = 0; var10 < var9; ++var10) {
        ppName = var8[var10];
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            pp = (BeanPostProcessor)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);
        }
    }

    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
    Iterator var14 = orderedPostProcessorNames.iterator();

    while(var14.hasNext()) {
        String ppName = (String)var14.next();
        BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }

    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
    Iterator var17 = nonOrderedPostProcessorNames.iterator();

    while(var17.hasNext()) {
        ppName = (String)var17.next();
        pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }

    registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
在这个方法中 首先通过类型拿到容器中所有需要创建的后置处理器的名称数组postProcessorNames,这些后置处理器此时还没被创建出来,还只是一些定义。包括了初始化容器所需的默认的一些后置处理器以及@EnableAspectJAutoProxy 中所需要创建的AnnotationAwareAspectJAutoProxyCreator的类的定义。此时这个postProcessorNames中就包含了一个叫做org.springframework.aop.config.internalAutoProxyCreator的后置处理器的beanDefinition的定义信息,它所对应的类其实就是AnnotationAwareAspectJAutoProxyCreator。这一步是在2.1中就已经做好了的。接下来我们就会通过这些beanDefinition信息来创建后置处理器对象。在上述代码中,后面它对这些后置处理器做了一系列排序,而AnnotationAwareAspectJAutoProxyCreator是实现了Ordered接口的所以走到
while(var14.hasNext()) {
        String ppName = (String)var14.next();
        BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
这个方法中,可以看到首先通过beanFactory获取这个对象,这之后就是调用springioc中的doGetBean方法,而这个方法其实就是springioc用来创建bean实例对象的方法,在第一次调用初始化时,容器中是没有这个bean实例的,所以他会最终调用到AbstractAutowireCapableBeanFactory的doCreateBean方法,这个方法有几行代码特别重要
//实例化对象出来以后,进行属性赋值
populateBean(beanName, mbd, instanceWrapper);
	if (exposedObject != null) {
		//初始化bean
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
在initializeBean这个方法中
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
				invokeAwareMethods(beanName, bean);
				return null;
			}
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}

	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}
	return wrappedBean;
}
我们可以看到主要有4步
1) 首先调用invokeAwareMethods方法,此方法是处理实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这三个接口的类,而我们之前观察AnnotationAwareAspectJAutoProxyCreator的层级关系,可以知道他是实现了BeanFactoryAware接口的,所以他会执行invokeAwareMethods方法的如下代码:
	if (bean instanceof BeanFactoryAware) {
		((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
	}
可以看到它是调用了setBeanFactory,而这个setBeanFactory是在AnnotationAwareAspectJAutoProxyCreator的父类AbstractAdvisorAutoProxyCreator中重写了
public void setBeanFactory(BeanFactory beanFactory) {
    super.setBeanFactory(beanFactory);
    if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
        throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
    } else {
        this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
    }
}

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
这一步骤主要是生成了一个BeanFactoryAdvisorRetrievalHelperAdapter对象
2)调用wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);方法,这个方法内部主要是拿出所有的后置处理器,调用他们的postProcessBeforeInitialization方法
3) 调用invokeInitMethods(beanName, wrappedBean, mbd);方法,这个方法是调用初始化方法,就是在定义bean的时候指定的方法(@Bean(initMethod =xxx))
4) 调用wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);方法,这个方法内部主要是拿出所有的后置处理器,调用他们的postProcessAfterInitialization
至此spring将这个AnnotationAwareAspectJAutoProxyCreator对象创建出来,并调用了当中的setBeanFactory方法,最后会在上面的PostProcessorRegistrationDelegate的registerBeanPostProcessors方法中调用registerBeanPostProcessors将所创建出来的后置处理器加入到一个list中,以待后面使用
2.4 AOP流程的具体实现
在2.3中,AnnotationAwareAspectJAutoProxyCreator对象已经被创建并注册了,因此后面的其他任何对象在要被创建时,都会调用这个新加入的后置处理器的postProcessBeforeInitialization以及postProcessAfterInitialization方法。接下来我们就要研究AnnotationAwareAspectJAutoProxyCreator是怎么运行的
通过观察AnnotationAwareAspectJAutoProxyCreator的父类结构可知在他的父类AbstractAutoProxyCreator中实现了SmartInstantiationAwareBeanPostProcessor接口,而这个接口又是InstantiationAwareBeanPostProcessor接口的子类,在InstantiationAwareBeanPostProcessor接口中就定义了postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法,注意:这两个方法和上面所述的postProcessBeforeInitialization及postProcessAfterInitialization方法不同,一个是实例化之前及之后执行,一个是初始化之前及之后执行,方法名有细微差别,不要搞混淆。)
而AbstractAutoProxyCreator中重写的postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法是在容器初始化时的refresh方法的this.finishBeanFactoryInitialization(beanFactory);方法中,这个方法是完成剩下的bean的创建。finishBeanFactoryInitialization方法的最后一行代码就是进行创建工作
beanFactory.preInstantiateSingletons();
而这个方法中又调用了getBean->doGetBean->createBean流程,而在createBean方法中,有如下代码
// Give BeanPostProcessors a chance to return a proxy instead of the target 	bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
由注释可知,此方法是给后置处理器一个机会去干预bean对象的生成,来生成代理对象而不是原对象,点进这个方法中
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}
可以看到在此处调用了applyBeanPostProcessorsBeforeInstantiation方法及applyBeanPostProcessorsAfterInitialization方法(后面会讲),我们先点进去applyBeanPostProcessorsBeforeInstantiation方法
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
	}
	return null;
}
此时又是拿出所有的后置处理器,判断他是不是InstantiationAwareBeanPostProcessor的实例,而由前面可知我们生成的AnnotationAwareAspectJAutoProxyCreator后置处理器是实现了SmartInstantiationAwareBeanPostProcessor接口,而这个类又继承至InstantiationAwareBeanPostProcessor接口,所以最后会调用上述方法中的 ibp.postProcessBeforeInstantiation(beanClass, beanName);方法,由此我们得知InstantiationAwareBeanPostProcessor这个后置处理器是在实例化对象之前调用,尝试返回一个对象,BeanPostProcessor后置处理器是在初始化对象前后调用,他们是不一样的后置处理器。而这个postProcessBeforeInstantiation方法其实是定义到AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法,他重写了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
 public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    Object cacheKey = this.getCacheKey(beanClass, beanName);
    if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }

        if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    if (beanName != null) {
        TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            this.targetSourcedBeans.add(beanName);
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
    }

    return null;
}
上述代码中
1) 首先通过this.advisedBeans.containsKey(cacheKey)判断是否是需要增强的bean
2) 然后通过this.isInfrastructureClass(beanClass)判断是否是Advice、Pointcut、Advisor、AopInfrastructureBean这些基础类型的bean以及通过this.shouldSkip(beanClass, beanName)判断是否需要跳过
3)判断自定义的targetSource,此时肯定是null,所以直接返回。
我们接着上面的resolveBeforeInstantiation方法讲,上面讲完了其中的applyBeanPostProcessorsBeforeInstantiation方法的逻辑,接下来我们要讲applyBeanPostProcessorsAfterInitialization方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}
这个方法内部调用了后置处理器的postProcessAfterInitialization方法,而此方法也在AbstractAutoProxyCreator类中进行了重写
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return this.wrapIfNecessary(bean, beanName, cacheKey);
        }
    }

    return bean;
}
这里我们主要研究wrapIfNecessary方法做了什么,首先我们观察方法名,包装如果需要的话,我们可以猜测,这个方法就是代理增强我们homeDao的home方法的
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
        Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    } else {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
}
1) getAdvicesAndAdvisorsForBean方法,获取当前bean的增强器,也就是我们homeDao的所有通知方法,由下图可知,其中有5个增强器,第一个默认的增强器,及其余四个我们在MyAspect类中自定义的4个通知
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190821113702937.png)
2)将当前bean保存到advisedBeans集合中,表示此bean已经被增强过了。
3) 调用this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean))生成代理对象。
2.5 如何生成的代理对象
由2.4中我们已经生成了代理对象,但是我们可以深入研究一下代理对象是如何生成的,我们点进this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean))方法中,最终会定位到AbstractAutoProxyCreator类中的createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource)方法。
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
    }

    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
    if (!proxyFactory.isProxyTargetClass()) {
        if (this.shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        } else {
            this.evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    this.customizeProxyFactory(proxyFactory);
    proxyFactory.setFrozen(this.freezeProxy);
    if (this.advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(this.getProxyClassLoader());
}
我们看到他是由ProxyFactory代理工厂来生成代理对象的。
1) 首先是通过this.buildAdvisors(beanName, specificInterceptors)获取所有的增强器(通知方法)
2) 通过proxyFactory.addAdvisors(advisors),将增强器加入到代理工厂
3)通过 proxyFactory.setTargetSource(targetSource),将被代理对象加入到代理工厂
4) 最后通过proxyFactory.getProxy(this.getProxyClassLoader()),返回代理对象。
我们点进getProxy方法中,最终定位到DefaultAopProxyFactory类中的createAopProxy方法,此方法就是spring生成动态代理的方法
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
        return new JdkDynamicAopProxy(config);
    } else {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
        } else {
            return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
        }
    }
}
由于我们homeDao没有实现接口,所以最终我们生成了由cglib代理的homeDao代理对象

3 spring按照顺序执行通知方法—拦截器链

我们对homeDao的home方法打上断点,通过step into进入到CglibAopProxy.DynamicAdvisedIntercepto的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;

        Object var15;
        try {
            if (this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            target = this.getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }

            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            Object retVal;
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = methodProxy.invoke(target, argsToUse);
            } else {
                retVal = (new CglibAopProxy.CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();
            }

            retVal = CglibAopProxy.processReturnType(proxy, target, method, retVal);
            var15 = retVal;
        } finally {
            if (target != null) {
                this.releaseTarget(target);
            }

            if (setProxyContext) {
                AopContext.setCurrentProxy(oldProxy);
            }

        }

        return var15;
    }
上述方法就是拦截目标方法的,其中有一行代码 List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 这个方法就是通过proxyFactory获取目标方法将要执行的拦截器链(通知)。这个method就是我们的home方法,而这个targetClass就是我们的home对象。
1) getInterceptorsAndDynamicInterceptionAdvice内部中会创建一个和我们通知个数大小一样的list,然后遍历所有的advisor(增强器),将其转换为MethodInterceptor对象,存在这个list中,最后返回。
2) 接下来判断,如果拦截器链是空的并且目标方法是public的,那么直接调用invoke方法执行目标方法,也就是我们写的home方法
3) 否则,会new一个CglibAopProxy.CglibMethodInvocation对象并调用他的proceed方法
我们进入proceed方法中
public Object proceed() throws Throwable {
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return this.invokeJoinpoint();
    } else {
        Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
            return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
        } else {
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}
首先进入这个方法时,有一个this.currentInterceptorIndex属性,这个属性默认为-1,而this.interceptorsAndDynamicMethodMatchers.size() -1为4,因为之前我们知道总共有5个增强器,1个默认的,4个我们写的通知方法。如果拦截器链个数为0,或者执行到了最后一个拦截器(因为后面会对currentInterceptorIndex属性做++操作),那么会执行invokeJoinpoint方法,这个方法内部就是给非public方法一个执行权限,然后执行目标方法(home方法)
由于我们有5个拦截器链,所以会来到else中,他先执行this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex)方法,获取第0个拦截器,判断是不是InterceptorAndDynamicMethodMatcher的实例对象,因为我们的5个拦截器链都不是,所以都会调用return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);方法,这个this就是当前对象CglibMethodInvocation对象。
第一个interceptorOrInterceptionAdvice是默认的ExposeInvocationInterceptor拦截器,我们查看他的invoke方法
//ExposeInvocationInterceptor的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
    invocation.set(mi);

    Object var3;
    try {
        var3 = mi.proceed();
    } finally {
        invocation.set(oldInvocation);
    }

    return var3;
}
他先从invocation中去获取,而这个invocation是一个ThreadLocal,第一次没有,所以将CglibMethodInvocation对象mi放入invocation中,然后调用mi.proceed()方法,也就是之前的方法。
第二次由于currentInterceptorIndex 已经变为0,还是走之前逻辑,这次interceptorsAndDynamicMethodMatchers.get(1)方法获取到的是AspectJAfterThrowingAdvice拦截器,我们进入他的invoke方法
//AspectJAfterThrowingAdvice的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    try {
        return mi.proceed();
    } catch (Throwable var3) {
        if (this.shouldInvokeOnThrowing(var3)) {
            this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
        }

        throw var3;
    }
}
这个方法直接又调用proceed方法,由此我们可以知道这个方法会循环调用所有的拦截器的invoke方法,我们把这个调用链打出来ExposeInvocationInterceptor-》AspectJAfterThrowingAdvice-》AspectJAfterReturningAdvice-》AspectJAfterAdvice-》AspectJMethodBeforeAdvice,我们将5个拦截器链的invoke方法放在下面,分析他们具体是怎么运行的
//ExposeInvocationInterceptor的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    MethodInvocation oldInvocation = (MethodInvocation)invocation.get();
    invocation.set(mi);

    Object var3;
    try {
        var3 = mi.proceed();
    } finally {
        invocation.set(oldInvocation);
    }

    return var3;
}

//AspectJAfterThrowingAdvice的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    try {
        return mi.proceed();
    } catch (Throwable var3) {
        if (this.shouldInvokeOnThrowing(var3)) {
            this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
        }

        throw var3;
    }
}

//AspectJAfterReturningAdvice的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    Object retVal = mi.proceed();
    this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
    return retVal;
}

//AspectJAfterAdvice的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    Object var2;
    try {
        var2 = mi.proceed();
    } finally {
        this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);
    }

    return var2;
}

//AspectJMethodBeforeAdvice的invoke方法
public Object invoke(MethodInvocation mi) throws Throwable {
    this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
    return mi.proceed();
}
由上可见在最后调用AspectJMethodBeforeAdvice的invoke方法时,他先调用了this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());方法,而这个方法就是调用前置通知的方法(我们写的@Before方法),所以控制台会打印出before…,然后才会调用mi.proceed方法
此时我们索引已经增为4了,所以proceed方法会调用return this.invokeJoinpoint();方法,调用目标方法(home方法)。
由于方法已返回,所以又会返回到AspectJAfterAdvice的invoke方法,进入他的finally代码块, this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, (Throwable)null);,此时会执行后置处理器(@After)的方法,控制台打印after…。
当我们后置通知没有发生异常,那么就会来到AspectJAfterReturningAdvice的invoke方法,执行this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());方法(调用@AfterReturning的方法),控制台会打印afterReturning…,如果有异常,他会直接往上抛
如果发生了异常,则会调用AspectJAfterThrowingAdvice的invoke方法中的catch代码块
if (this.shouldInvokeOnThrowing(var3)) {
    this.invokeAdviceMethod(this.getJoinPointMatch(), (Object)null, var3);
}
执行异常通知,打印afterThrowing…
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值