Spring框架进阶Spring V3.0 AOP源码分析流程

Posted 烟锁迷城

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架进阶Spring V3.0 AOP源码分析流程相关的知识,希望对你有一定的参考价值。

目录

1、总体分析

2、源码分析

3、流程总结

3.1、创建代理类

3.1.1、读取通知

3.1.2、进行代理

3.2、代码织入

3.2.1、拦截器

3.2.2、调用器

3.3、响应回调

4、核心思想


1、总体分析

在Spring的设计之中,AOP发生在实例化的过程中,在符合代理要求的情况下,返回的类从原生类改为代理类。

整个代理切面方法会被组成一个代理链,通过递归的方式,将它们按顺序执行。

总体流程大致为

  1. 寻找入口
  2. 选择策略
  3. 调用方法
  4. 触发通知

2、源码分析

回到上一节DI之中,可以看到,之前提到过在doCreateBean方法之中,有两个方法,一个是实例化方法createBeanInstance,一个是依赖注入方法pupolateBean。

protected Object  doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
		throws BeanCreationException 

	// Instantiate the bean.
	//封装被创建的Bean对象
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) 
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	
	if (instanceWrapper == null) 
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	
	final Object bean = instanceWrapper.getWrappedInstance();
	//获取实例化对象的类型
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) 
		mbd.resolvedTargetType = beanType;
	

	// Allow post-processors to modify the merged bean definition.
	//调用PostProcessor后置处理器
	synchronized (mbd.postProcessingLock) 
		if (!mbd.postProcessed) 
			try 
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			
			catch (Throwable ex) 
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			
			mbd.postProcessed = true;
		
	

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	//向容器中缓存单例模式的Bean对象,以防循环引用
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) 
		if (logger.isDebugEnabled()) 
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		
		//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	

	// Initialize the bean instance.
	//Bean对象的初始化,依赖注入在此触发
	//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
	Object exposedObject = bean;
	try 
		//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
		populateBean(beanName, mbd, instanceWrapper);
		//初始化Bean对象
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	
	catch (Throwable ex) 
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) 
			throw (BeanCreationException) ex;
		
		else 
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		
	

	if (earlySingletonExposure) 
		//获取指定名称的已注册的单例模式Bean对象
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) 
			//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
			if (exposedObject == bean) 
				//当前实例化的Bean初始化完成
				exposedObject = earlySingletonReference;
			
			//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) 
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				//获取当前Bean所依赖的其他Bean
				for (String dependentBean : dependentBeans) 
					//对依赖Bean进行类型检查
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) 
						actualDependentBeans.add(dependentBean);
					
				
				if (!actualDependentBeans.isEmpty()) 
					throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. This means that said other beans do not use the final version of the " +
							"bean. This is often the result of over-eager type matching - consider using " +
							"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
				
			
		
	

	// Register bean as disposable.
	//注册完成依赖注入的Bean
	try 
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	
	catch (BeanDefinitionValidationException ex) 
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	

	return exposedObject;

在createBeanInstance方法中,起到实例化作用的是initializeBean,这个方法返回了需要的类

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 
	// Make sure bean class is actually resolved at this point.
	//检查确认Bean是可实例化的
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	//使用工厂方法对Bean进行实例化
	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) 
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	

	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) 
		return obtainFromSupplier(instanceSupplier, beanName);
	

	if (mbd.getFactoryMethodName() != null)  
		//调用工厂方法实例化
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	

	// Shortcut when re-creating the same bean...
	//使用容器的自动装配方法进行实例化
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) 
		synchronized (mbd.constructorArgumentLock) 
			if (mbd.resolvedConstructorOrFactoryMethod != null) 
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			
		
	
	if (resolved) 
		if (autowireNecessary) 
			//配置了自动装配属性,使用容器的自动装配实例化
			//容器的自动装配是根据参数类型匹配Bean的构造方法
			return autowireConstructor(beanName, mbd, null, null);
		
		else 
			//使用默认的无参构造方法实例化
			return instantiateBean(beanName, mbd);
		
	

	// Need to determine the constructor...
	//使用Bean的构造方法进行实例化
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  
		//使用容器的自动装配特性,调用匹配的构造方法实例化
		return autowireConstructor(beanName, mbd, ctors, args);
	

	// No special handling: simply use no-arg constructor.
	//使用默认的无参构造方法实例化
	return instantiateBean(beanName, mbd);

在initializeBean方法中,可以看到,

beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    getInstantiationStrategy().instantiate(mbd, beanName, parent),
                    getAccessControlContext());

这是一段lambda表达式,在其中明显有一个实例化策略getInstantiationStrategy(),这个策略是什么呢?是来自于DefaultAutowireCapableBeanFactory的一个成员变量,Cglib代理策略,这是默认的代理策略

private InstantiationStrategy instantiationStrategy = 
                                new CglibSubclassingInstantiationStrategy();
protected InstantiationStrategy getInstantiationStrategy() 
	return this.instantiationStrategy;


protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) 
	try 
		Object beanInstance;
		final BeanFactory parent = this;
		//获取系统的安全管理接口,JDK标准的安全管理API
		if (System.getSecurityManager() != null) 
			//这里是一个匿名内置类,根据实例化策略创建实例对象
			beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
					getInstantiationStrategy().instantiate(mbd, beanName, parent),
					getAccessControlContext());
		
		else 
			//将实例化的对象封装起来
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
		
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	
	catch (Throwable ex) 
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	

那么doCreateBean方法中createBeanInstance方法返回的封装BeanWrapper是否就会被直接返回呢?并不是

Object exposedObject = bean,之中的bean来源于BeanWrapper,的确是实例化或是从实例缓存中拿到的,但是它还经过了两个步骤,其一是initializeBean,其二是循环依赖的检测,才会返回。

循环依赖自不必说,如果创建的Bean和缓存中的bean是一致的,就会被缓存中的替换。

但是很显然,那个从initializeBean(初始化Bean)方法中得到的Bean也替换了exposedObject,在这之中又进行了什么操作呢?

Object exposedObject = bean;
try 
	//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
	populateBean(beanName, mbd, instanceWrapper);
	//初始化Bean对象
	exposedObject = initializeBean(beanName, exposedObject, mbd);

catch (Throwable ex) 
	if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) 
		throw (BeanCreationException) ex;
	
	else 
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
	


if (earlySingletonExposure) 
	//获取指定名称的已注册的单例模式Bean对象
	Object earlySingletonReference = getSingleton(beanName, false);
	if (earlySingletonReference != null) 
		//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
		if (exposedObject == bean) 
			//当前实例化的Bean初始化完成
			exposedObject = earlySingletonReference;
		
		//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
		else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) 
			String[] dependentBeans = getDependentBeans(beanName);
			Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
			//获取当前Bean所依赖的其他Bean
			for (String dependentBean : dependentBeans) 
				//对依赖Bean进行类型检查
				if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) 
					actualDependentBeans.add(dependentBean);
				
			
			if (!actualDependentBeans.isEmpty()) 
				throw new BeanCurrentlyInCreationException(beanName,
						"Bean with name '" + beanName + "' has been injected into other beans [" +
						StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
						"] in its raw version as part of a circular reference, but has eventually been " +
						"wrapped. This means that said other beans do not use the final version of the " +
						"bean. This is often the result of over-eager type matching - consider using " +
						"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
			
		
	


// Register bean as disposable.
//注册完成依赖注入的Bean
try 
	registerDisposableBeanIfNecessary(beanName, bean, mbd);

catch (BeanDefinitionValidationException ex) 
	throw new BeanCreationException(
			mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);


return exposedObject;

initializeBean方法的参数有三个,是CreateBeanInstance中的initializeBean方法的一个重载方法,三个参数的initializeBean会额外传递一个已经完成依赖注入的类,这意味着暴露类中的一些参数是这个方法所需要的。

applyBeanPostProcessorsBeforeInitialization:初始化前置处理

invokeInitMethods:初始化

applyBeanPostProcessorsAfterInitialization:初始化后置处理

代理一定是初始化之后才进行代理,所以看后置处理方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) 
	//JDK的安全机制验证权限
	if (System.getSecurityManager() != null) 
		//实现PrivilegedAction接口的匿名内部类
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> 
			invokeAwareMethods(beanName, bean);
			return null;
		, getAccessControlContext());
	
	else 
		//为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
		invokeAwareMethods(beanName, bean);
	

	Object wrappedBean = bean;
	//对BeanPostProcessor后置处理器的postProcessBeforeInitialization
	//回调方法的调用,为Bean实例初始化前做一些处理
	if (mbd == null || !mbd.isSynthetic()) 
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	

	//调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
	//文件中通过init-method属性指定的
	try 
		invokeInitMethods(beanName, wrappedBean, mbd);
	
	catch (Throwable ex) 
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	
	//对BeanPostProcessor后置处理器的postProcessAfterInitialization
	//回调方法的调用,为Bean实例初始化之后做一些处理
	if (mbd == null || !mbd.isSynthetic()) 
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	

	return wrappedBean;

可以看到,applyBeanPostProcessorsAfterInitialization方法里的实现,比较关键的是自定义的处理操作,也就是BeanPostProcessor的postProcessAfterInitialization方法,实际上这个方法的实现类有很多,但我们只看AbstractAutoProxyCreator实现类的,因为这是代理创建者

@Override
//调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException 

	Object result = existingBean;
	//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) 
		//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
		//初始化之后做一些自定义的处理操作
		Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (current == null) 
			return result;
		
		result = current;
	
	return result;

 AbstractAutoProxyCreator类看关键方法wrapIfNecessary(bean, beanName, cacheKey)

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException 
	if (bean != null) 
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) 
			return wrapIfNecessary(bean, beanName, cacheKey);
		
	
	return bean;

warpIfNecessary方法的前半部分是一些判断读取缓存的操作,关键在于getAdvicesAndAdvisorsForBean方法,这个方法是去获取对象对应的通知。

如果获取到通知,就返回代理类,如果没有通知,那么就不必代理,继续返回原来的初始化类即可

所以接下来的操作就分为读取通知进行代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) 
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) 
		return bean;
	
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) 
		return bean;
	
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) 
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	

	// Create proxy if we have advice.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) 
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;

获取到所有的通知,如果通知为空,则返回空,反之返回通知队列

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) 
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) 
		return DO_NOT_PROXY;
	
	return advisors.toArray();

查找所有的通知,然后去除重复,如果得到结果不为空,对通知进行排序

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) 
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) 
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	
	return eligibleAdvisors;

 可以看到,排序的方法是一个比较器提供的,在这个比较器中,执行doCompare方法,按照优先级进行排序

protected List<Advisor> sortAdvisors(List<Advisor> advisors) 
	AnnotationAwareOrderComparator.sort(advisors);
	return advisors;


private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) 
	boolean p1 = (o1 instanceof PriorityOrdered);
	boolean p2 = (o2 instanceof PriorityOrdered);
	if (p1 && !p2) 
		return -1;
	
	else if (p2 && !p1) 
		return 1;
	

	// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
	int i1 = getOrder(o1, sourceProvider);
	int i2 = getOrder(o2, sourceProvider);
	return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;

读取通知结束之后,就进行代理操作。

回到wrapIfNecessary方法中,可以看到,如果通知,就进行代理操作,createProxy方法

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) 
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    Object proxy = createProxy(
        bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;

可以看到。这里proxyFactory放入了一些数据,包括通知,目标资源等,最后执行

proxyFactory.getProxy方法

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
		@Nullable 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 (shouldProxyTargetClass(beanClass, beanName)) 
			proxyFactory.setProxyTargetClass(true);
		
		else 
			evaluateProxyInterfaces(beanClass, proxyFactory);
		
	

	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) 
		proxyFactory.setPreFiltered(true);
	

	return proxyFactory.getProxy(getProxyClassLoader());

 在ProFactory的getProxy中,可以得到创建方法,继续向下,可以看到,如果有接口继承,就使用JDK代理,否则使用CGlib方式

public Object getProxy(@Nullable ClassLoader classLoader) 
    return createAopProxy().getProxy(classLoader);


protected final synchronized AopProxy createAopProxy() 
	if (!this.active) 
		activate();
	
	return getAopProxyFactory().createAopProxy(this);


public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException 
	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) 
		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.");
		
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) 
			return new JdkDynamicAopProxy(config);
		
		return new ObjenesisCglibAopProxy(config);
	
	else 
		return new JdkDynamicAopProxy(config);
	

接下来以JDK代理为例。

getProxy方法来自JdkDynamicAopProxy,实际上这个方法来自于JdkDynamicAopProxy的接口AopProxy,目的是统一两种代理方式获取代理的入口。

newProxyInstance,最后创建代理类的方法

public Object getProxy(@Nullable ClassLoader classLoader) 
	if (logger.isDebugEnabled()) 
		logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
	
	Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

 在完成代理类的实现之后,真正要关注的还是代理的invoke方法

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

这里应用的是责任链模式,将通知装载到责任链之中,依照顺序进行执行。

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;

	TargetSource targetSource = this.advised.targetSource;
	Object target = null;

	try 
		//eqauls()方法,具目标对象未实现此方法
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) 
			// The target does not implement the equals(Object) method itself.
			return equals(args[0]);
		
		//hashCode()方法,具目标对象未实现此方法
		else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) 
			// The target does not implement the hashCode() method itself.
			return hashCode();
		
		else if (method.getDeclaringClass() == DecoratingProxy.class) 
			// There is only getDecoratedClass() declared -> dispatch to proxy config.
			return AopProxyUtils.ultimateTargetClass(this.advised);
		
		//Advised接口或者其父接口中定义的方法,直接反射调用,不应用通知
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
				method.getDeclaringClass().isAssignableFrom(Advised.class)) 
			// Service invocations on ProxyConfig with the proxy config...
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		

		Object retVal;

		if (this.advised.exposeProxy) 
			// Make invocation available if necessary.
			oldProxy = AopContext.setCurrentProxy(proxy);
			setProxyContext = true;
		

		// Get as late as possible to minimize the time we "own" the target,
		// in case it comes from a pool.
		//获得目标对象的类
		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);

		// Get the interception chain for this method.
		//获取可以应用到此方法上的Interceptor列表
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

		// Check whether we have any advice. If we don't, we can fallback on direct
		// reflective invocation of the target, and avoid creating a MethodInvocation.
		//如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
		if (chain.isEmpty()) 
			// We can skip creating a MethodInvocation: just invoke the target directly
			// Note that the final invoker must be an InvokerInterceptor so we know it does
			// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		
		else 
			// We need to create a method invocation...
			//创建MethodInvocation
			invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
			// Proceed to the joinpoint through the interceptor chain.
			retVal = invocation.proceed();
		

		// Massage return value if necessary.
		Class<?> returnType = method.getReturnType();
		if (retVal != null && retVal == target &&
				returnType != Object.class && returnType.isInstance(proxy) &&
				!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) 
			// Special case: it returned "this" and the return type of the method
			// is type-compatible. Note that we can't help if the target sets
			// a reference to itself in another returned object.
			retVal = proxy;
		
		else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) 
			throw new AopInvocationException(
					"Null return value from advice does not match primitive return type for: " + method);
		
		return retVal;
	
	finally 
		if (target != null && !targetSource.isStatic()) 
			// Must have come from TargetSource.
			targetSource.releaseTarget(target);
		
		if (setProxyContext) 
			// Restore old proxy.
			AopContext.setCurrentProxy(oldProxy);
		
	

 getInterceptorsAndDynamicInterceptionAdvice方法中,将方法Method作为生成缓存key的参数,进入到MethodCacheKey类中可以看到,其内部是由method和其hashcode组成,这里的目的是重写equal和hashcode方法,为放入到Map容器中做准备(至于为什么要重写equal和hashcode是一个小小的知识点,这里不做赘述)。

key生成完成之后,将在methodCache缓存中进行查找,那么这个缓存是什么呢?

是一个map,一个32大小的ConcurrentHashMap,且禁止序列化。

Map<MethodCacheKey, List<Object>> methodCache

如果没有得到对应的缓存,就获取到通知列表,并放入缓存中,如果获取到了,就直接返回即可

那么接下来的重点就是AdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法,获取通知列表

private transient Map<MethodCacheKey, List<Object>> methodCache;

public AdvisedSupport() 
    this.methodCache = new ConcurrentHashMap<>(32);


public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) 
	MethodCacheKey cacheKey = new MethodCacheKey(method);
	List<Object> cached = this.methodCache.get(cacheKey);
	if (cached == null) 
		cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
				this, method, targetClass);
		this.methodCache.put(cacheKey, cached);
	
	return cached;

 getInterceptorsAndDynamicInterceptionAdvice方法返回的就是一个Object列表,interceptorList,那么在这里放入的是什么呢?是MethodInterceptor

可以看到addAll方法放入的是MethodInterceptor,add方法放入的是InterceptorAndDynamicMethodMatcher,实际上其内部是MethodInterceptor和MethodMatcher两个属性,本质依旧是MethodInterceptor。

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
		Advised config, Method method, @Nullable Class<?> targetClass) 

	// This is somewhat tricky... We have to process introductions first,
	// but we need to preserve order in the ultimate list.
	List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
	Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
	//查看是否包含IntroductionAdvisor
	boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
	//这里实际上注册一系列AdvisorAdapter,用于将Advisor转化成MethodInterceptor
	AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

	for (Advisor advisor : config.getAdvisors()) 
		if (advisor instanceof PointcutAdvisor) 
			// Add it conditionally.
			PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
			if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) 
				//这个地方这两个方法的位置可以互换下
				//将Advisor转化成Interceptor
				MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
				//检查当前advisor的pointcut是否可以匹配当前方法
				MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
				if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) 
					if (mm.isRuntime()) 
						// Creating a new object instance in the getInterceptors() method
						// isn't a problem as we normally cache created chains.
						for (MethodInterceptor interceptor : interceptors) 
							interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
						
					
					else 
						interceptorList.addAll(Arrays.asList(interceptors));
					
				
			
		
		else if (advisor instanceof IntroductionAdvisor) 
			IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
			if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) 
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			
		
		else 
			Interceptor[] interceptors = registry.getInterceptors(advisor);
			interceptorList.addAll(Arrays.asList(interceptors));
		
	

	return interceptorList;

得到拦截器之后,回到 JdkDynamicAopProxy之中,继续向下

可以看到,接下来的关键是如果拦截器不为空,则执行invocation.proceed,这是一个调用器,可以视作责任链模式的上下文,作为依次执行拦截器的启动

if (chain.isEmpty()) 
	// We can skip creating a MethodInvocation: just invoke the target directly
	// Note that the final invoker must be an InvokerInterceptor so we know it does
	// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
	Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
	retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);

else 
	// We need to create a method invocation...
	//创建MethodInvocation
	invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
	// Proceed to the joinpoint through the interceptor chain.
	retVal = invocation.proceed();


// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
		returnType != Object.class && returnType.isInstance(proxy) &&
		!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) 
	// Special case: it returned "this" and the return type of the method
	// is type-compatible. Note that we can't help if the target sets
	// a reference to itself in another returned object.
	retVal = proxy;

else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) 
	throw new AopInvocationException(
			"Null return value from advice does not match primitive return type for: " + method);

return retVal;

 ReflectiveMethodInvocation类的process方法,可以看到这里面的操作已经是类似递归调用的责任链方式。

如果全部拦截都执行完了,则返回joinpoint切点,否则当前游标自增,获取到当前应该执行的拦截器。如果符合动态匹配标准,调用拦截器的invoke方法,否则递归调用,获取到下一个拦截器。

那么很明显,精华部分在于dm.interceptor.invoke方法

public Object proceed() throws Throwable 
	//	We start with an index of -1 and increment early.
	//如果Interceptor执行完了,则执行joinPoint
	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) 
		return invokeJoinpoint();
	

	Object interceptorOrInterceptionAdvice =
			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
	//如果要动态匹配joinPoint
	if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) 
		// Evaluate dynamic method matcher here: static part will already have
		// been evaluated and found to match.
		InterceptorAndDynamicMethodMatcher dm =
				(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
		//动态匹配:运行时参数是否满足匹配条件
		if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) 
			return dm.interceptor.invoke(this);
		
		else 
			// Dynamic matching failed.
			// Skip this interceptor and invoke the next in the chain.
			//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
			return proceed();
		
	
	else 
		// It's an interceptor, so we just invoke it: The pointcut will have
		// been evaluated statically before this object was constructed.
		//执行当前Intercetpor
		return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
	

 事实上,dm.interceptor.invoke有很多的实现,可以挑几个具有代表性的看看

首先带有Before的MethodBeforeAdviceInterceptor

可以看到,这个方法的构造会把要执行的目标对象放入,在执行invoke方法之前,会把目标对象的before方法,即真正要执行的方法先行执行,然后执行自身的process方法,将责任链向下推进

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable 

	private MethodBeforeAdvice advice;


	/**
	 * Create a new MethodBeforeAdviceInterceptor for the given advice.
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) 
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable 
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	

接下来看一个after的拦截器AfterReturningAdviceInterceptor

可以清晰地看到,这里先执行到责任链的下一个拦截器的方法process,然后才执行目标对象要执行的after方法,巧妙地保证了执行的顺序

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable 

	private final AfterReturningAdvice advice;


	/**
	 * Create a new AfterReturningAdviceInterceptor for the given advice.
	 * @param advice the AfterReturningAdvice to wrap
	 */
	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) 
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable 
		Object retVal = mi.proceed();
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	

 然后是afterThrow的拦截器AspectJAfterThrowingAdvice ,这里可以看到,是在抛错的情况下,才会执行对应的目标方法

public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice
		implements MethodInterceptor, AfterAdvice, Serializable 

	public AspectJAfterThrowingAdvice(
			Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) 

		super(aspectJBeforeAdviceMethod, pointcut, aif);
	


	@Override
	public boolean isBeforeAdvice() 
		return false;
	

	@Override
	public boolean isAfterAdvice() 
		return true;
	

	@Override
	public void setThrowingName(String name) 
		setThrowingNameNoCheck(name);
	

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable 
		try 
			return mi.proceed();
		
		catch (Throwable ex) 
			if (shouldInvokeOnThrowing(ex)) 
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			
			throw ex;
		
	

	/**
	 * In AspectJ semantics, after throwing advice that specifies a throwing clause
	 * is only invoked if the thrown exception is a subtype of the given throwing type.
	 */
	private boolean shouldInvokeOnThrowing(Throwable ex) 
		return getDiscoveredThrowingType().isAssignableFrom(ex.getClass());
	


这样整个责任链都可以不用考虑after和before的执行顺序,而是直接按照顺序调用即可,非常巧妙 

3、流程总结

3.1、创建代理类

AbstractAutowireCapableBeanFactory:

initializeBean:在初始化和依赖注入之后执行的方法,创建暴露给外部的类,替换初始化之后的类。

AbstractAutowireCapableBeanFactory:

applyBeanPostProcessorsAfterInitialization:初始化的后置处理,代理在此完成

AbstractAutoProxyCreator:

wrapIfNecessary:读取通知方法getAdvicesAndAdvisorsForBean,进行代理方法createProxy,如果没有通知,则不必代理

3.1.1、读取通知

AbstractAdvisorAutoProxyCreator:

getAdvicesAndAdvisorsForBean:获取通知

AbstractAdvisorAutoProxyCreator:

findEligibleAdvisors:获取通知,去重,排序

AbstractAdvisorAutoProxyCreator:

sortAdvisors:通知排序,使用AnnotationAwareOrderComparator进行排序

3.1.2、进行代理

AbstractAdvisorAutoProxyCreator:

createProxy:创建代理类

ProxyFactory:

getProxy:创建代理对象

DefaultAopProxyFactory:

createAopProxy:根据条件创建代理方式

JdkDynamicAopProxy(AopProxy):

newProxyInstance:创建代理

3.2、代码织入

JdkDynamicAopProxy(AopProxy):

invoke:继承InvocationHandler之后必然会重写的方法,用于实现代理

3.2.1、拦截器

JdkDynamicAopProxy(AopProxy):

getInterceptorsAndDynamicInterceptionAdviceAdvisedSupport的方法,目的是将所有的通知同城一个拦截器,这里用到了责任链模式,将以method作为key,存放至methodCache,一个CurrentHashMap之中,如果没有获取到其中的缓存,就去调用getInterceptorsAndDynamicInterceptionAdvice来获取

AdvisedSupport:

getInterceptorsAndDynamicInterceptionAdvice:将advisor全部转化为MethodInterceptor,装载至列表中返回给缓存

3.2.2、调用器

JdkDynamicAopProxy(AopProxy):

proceed:拦截器链的上下文,属于被封装好的调用器ReflectiveMethodInvocation,启动整个拦截器链条

ReflectiveMethodInvocation:

invoke:在责任链中的每一个符合条件的拦截器都会调用此方法,执行回调响应

3.3、响应回调

MethodBeforeAdviceInterceptor:此处仅为例子,代表响应前置

before:目标对象的执行任务,真正要执行的方法,前置处理

process:责任链上下文,调用下一个责任链中的拦截器

AfterReturningAdviceInterceptor此处仅为例子,代表响应后置

process:责任链上下文,调用下一个责任链中的拦截器

after:目标对象的执行任务,真正要执行的方法,后置处理

AspectJAfterThrowingAdvice此处仅为例子,代表响应抛错

process:责任链上下文,调用下一个责任链中的拦截器

afterThrow:目标对象的执行任务,真正要执行的方法,仅在有错误的情况下执行

4、核心思想

整个AOP最核心的思想,除了代理,就是责任链中的拦截器,这里面包含两个类,MethodInterceptor(拦截器)MethodInvocation(调用器)。

MethodInterceptor:其内部的方法Invoke是代理增强的方法,在每一个MethodInterceptor的invoke方法之中,都依照通知的响应先后,决定是先执行目标方法还是执行责任链中的下一个拦截器,如before类型的拦截器,就先执行before,然后执行process方法调用下一个拦截器,after则反之

MethodInvocation:其内部的方法process串起了全部的拦截器,通过内部游标的自增计算,完成了全部拦截器的顺序调用。

以上是关于Spring框架进阶Spring V3.0 AOP源码分析流程的主要内容,如果未能解决你的问题,请参考以下文章

Spring框架进阶Spring V3.0 IOC源码分析流程

Spring框架进阶Spring V2.0 AOP

Spring入门到进阶 - Spring AOP

Spring框架进阶Spring V1.0

Spring框架进阶Spring V1.0

Spring 进阶二