【Spring源代码阅读之十三】Spring的AOP相关逻辑代码

前言

阅读Spring AOP相关代码,需要对Spring处理@Import注解的处理有了解,否则此处代码很难看懂执行的时机,可以参考我之前关于Spring处理@Import注解的文章,我这里只对AOP代码做解释,默认读者已经掌握@Import注解的处理逻辑了

引入AOP依赖(对源码环境而言)

/*
    aspectj表达式支持
    spring有自己的AOP处理逻辑,只不是引入了aspectj的表达式
*/
compile group: 'org.aspectj', name: 'aspectjrt', version: '1.8.13'
compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.13'

AOP逻辑类

@Aspect // 切面 切面包含多个切点 多个切点组成一个切面 (声明是一个AOP类)
@Component
public class AspectAop {

	@Pointcut("execution(* spring.framework.test.service.*.*(..))") //切点 指定程序执行的位置
	public void pointCut(){}

	@Before("pointCut()") //连接点 指定程序执行的时机
	public void before(){
		System.out.println("我在方法之前执行了"); // 增强 指定增强的逻辑
	}
}

@EnableAspectJAutoProxy(开启AOP支持)

/**
 * 开启AspectJ自动代理,Spring的Aspectj并没有原生使用Aspect,而是使用了他的表达式和理念
 * Aspect是静态代理,在编译期就改变原先类了
 * JDK和CGLIB是动态代理,在运行期动态改变类
 * 这里最重要的是Import了一个类
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

AspectJAutoProxyRegistrar

/**
 * 这个类是由{@link EnableAspectJAutoProxy}导入的
 * 作用是开启Aspect代理,这个类实现了ImportBeanDefinitionRegistrar接口,会在如下方法中处理
 * {@link ConfigurationClassParser#processImports(org.springframework.context.annotation.ConfigurationClass, org.springframework.context.annotation.ConfigurationClassParser.SourceClass, java.util.Collection, boolean)}
 */
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	/**
	 * 根据导入{@code@Configuration}类上的@{@link EnableAspectJAutoProxy}
	 * 属性的值注册、升级和配置AspectJ自动代理创建器。
	 * 这里最重要的是注册了一个BeanPostProcessor
	 * @see AnnotationAwareAspectJAutoProxyCreator
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		/**
		 * 这里注册了那个BeanPostProcessor,{@link AnnotationAwareAspectJAutoProxyCreator
		 * 注意:注册代码不解释,如果看到这里应该会看懂里面的代码
		 * 进行代理的代码在{@link AbstractAutoProxyCreator#postProcessAfterInitialization(java.lang.Object, java.lang.String)
		 */
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		/**
		 * 获取EnableAspectJAutoProxy注解中两个属性的值,如果不显示设置的话默认都是false
		 */
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

BeanPostProcessor注册过程

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
	return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
/**
 * 这里将类注册进Spring容器中,如果容器中存在则替换Class,不存在则建一个新的放进去
 */
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
		Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

	if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
		BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
		if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
			int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
			int requiredPriority = findPriorityForClass(cls);
			if (currentPriority < requiredPriority) {
				apcDefinition.setBeanClassName(cls.getName());
			}
		}
		return null;
	}

	RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
	beanDefinition.setSource(source);
	beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
	beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
	return beanDefinition;
}

AbstractAutoProxyCreator#postProcessAfterInitialization()

为什么会调用到这里
在上面说明的代码中向容器中注册了AnnotationAwareAspectJAutoProxyCreator类,它最上层接口实现了BeanPostProcessor接口,而接口的方法postProcessAfterInitialization实现在AbstractAutoProxyCreator类中,所以会调用到这里,而调用链这里做了个简单的引导,可以参考一下
在这里插入图片描述

/**
 * 为创建代理做准备
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		/**
		 * 获得统一的key标识
		 */
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		/**
		 * 如果集合删除返回值为null,则走一遍代理处理逻辑
		 */
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

wrapIfNecessary()

/**
 * 判断是否进行代理,及需要代理的类提取条件交由实际类进行代理
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	/**
	 * BeanName不合规并且在这个集合中存在,不代理,直接返回Bean
	 * 集合中存储已经被代理的类的key,因为在
	 * {@link AbstractAutoProxyCreator#postProcessBeforeInstantiation(java.lang.Class, java.lang.String)}
	 * 类中有可能已经代理了
	 */
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	/**
	 * 判断集合中key代表的类是否可以被代理,false表示不用代理,直接返回Bean
	 */
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	/**
	 * 判断是否需要被代理的条件,不符合的话加入到集合中,返回Bean
	 * @see AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass(java.lang.Class)
	 * @see AspectJAwareAdvisorAutoProxyCreator#shouldSkip(java.lang.Class, java.lang.String)
	 */
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	/**
	 * 视情况创建代理,这里如果存在给Bean添加代理的Advices
	 * @see AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(java.lang.Class, java.lang.String, org.springframework.aop.TargetSource)
	 */
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	/**
	 * 不为Null,则需要对Bean进行代理,执行代理方法,并放置进相应集合
	 */
	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;
}

isInfrastructureClass()

/**
 * 返回给定bean类是否代表不应该被代理的基础结构类。即类继承了这些类则不会被代理
 * <p>默认实现将Advices、Advisors和AopInfrastructureBeans视为基础结构类。
 */
protected boolean isInfrastructureClass(Class<?> beanClass) {
	boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
			Pointcut.class.isAssignableFrom(beanClass) ||
			Advisor.class.isAssignableFrom(beanClass) ||
			AopInfrastructureBean.class.isAssignableFrom(beanClass);
	if (retVal && logger.isTraceEnabled()) {
		logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
	}
	return retVal;
}

shouldSkip()

/**
 * 如果给定的bean不应被此后处理器视为自动代理,则子类应重写此方法以返回{@code true}。
 * <p>有时我们需要能够避免这种情况的发生,如果它将导致一个循环引用。此实现返回{@code false}。
 */
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	return false;
}

AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean()

/**
 * 根据Bean搜寻符合给这个Bean加代理条件的切点
 * 没有则返回null
 */
@Override
@Nullable
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();
}

findEligibleAdvisors()

/**
 * 找到所有符合条件的Advisors来自动代理这个类。
 *
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	/**
	 * 查找容器中实现了Advisor接口的类,此类可配置代理的条件
	 * @see AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
	 */
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	/**
	 * 找出符合给这个Bean加代理条件的Advisor
	 */
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	/**
	 * @see AspectJAwareAdvisorAutoProxyCreator#extendAdvisors(java.util.List)
	 */
	extendAdvisors(eligibleAdvisors);
	/**
	 * 不为空,则进行一下排序
	 */
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
/**
 * 查找容器中所有的Advisors
 */
@Override
protected List<Advisor> findCandidateAdvisors() {
	// Add all the Spring advisors found according to superclass rules.
	/**
	 * 添加根据超类规则找到的所有Advisors
	 */
	List<Advisor> advisors = super.findCandidateAdvisors();
	// Build Advisors for all AspectJ aspects in the bean factory.
	/**
	 * 为BeanFactory中的所有AspectJ注解构建Advisor。
	 */
	if (this.aspectJAdvisorsBuilder != null) {
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
	}
	return advisors;
}
findAdvisorsThatCanApply()
/**
 * 搜索给定的Bean以查找可以应用于指定bean的所有Advisors。
 */
protected List<Advisor> findAdvisorsThatCanApply(
		List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

	/**
	 * 设置当前代理bean实例的名称进本地线程中
	 */
	ProxyCreationContext.setCurrentProxiedBeanName(beanName);
	try {
		return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
	}
	finally {
		ProxyCreationContext.setCurrentProxiedBeanName(null);
	}
}
AopUtils#findAdvisorsThatCanApply()
/**
 * 对于Bean,返回Advisors列表中符合给这个Bean加代理的条件的一些Advisors
 * 重点在canApply方法上,大致的意思是拿到Bean中所有的Method,通过列表过滤一遍,查看是否符合
 */
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	if (candidateAdvisors.isEmpty()) {
		return candidateAdvisors;
	}
	List<Advisor> eligibleAdvisors = new ArrayList<>();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// already processed
			continue;
		}
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}
AspectJAwareAdvisorAutoProxyCreator#extendAdvisors()
/**
 * 将{@link ExposeInvocationInterceptor}添加到通知链的开头。
 * 使用AspectJ表达式切入点和使用AspectJ样式建议时,需要这些附加建议。
 * 暂不理解
 */
@Override
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
	AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}

createProxy()

/**
 * 给Bean执行代理
 */
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());
}

shouldProxyTargetClass()

/**
 * 确定给定bean是否应该用它的目标类而不是它的接口来代理。
 * <p>检查相应bean定义的{@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
 */
protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
	return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
			AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
}

ProxyFactory#getProxy()

/**
 * @see ProxyCreatorSupport#createAopProxy()
 */
public Object getProxy(@Nullable ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}
ProxyCreatorSupport#createAopProxy()
/**
 * @see DefaultAopProxyFactory#createAopProxy(org.springframework.aop.framework.AdvisedSupport)
 */
protected final synchronized AopProxy createAopProxy() {
	if (!this.active) {
		activate();
	}
	return getAopProxyFactory().createAopProxy(this);
}
DefaultAopProxyFactory#createAopProxy()
/**
 * 创建具体的代理策略
 */
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	/**
	 * 下方三个条件,只要有一个符合,则有可能使用CGLIB代理,否则直接使用JDK代理
	 *
	 * optimize属性
	 * 		恒定为false,可通过xml形式更改,Annotation形式目前没有找到直接形式的修改方式
	 * 	注意:此属性可通过proxyTargetClass属性的第二种方式修改,Import一个ImportBeanDefinitionRegistrar实现类修改
	 * proxyTargetClass属性
	 * 		1、在{@link AbstractAutoProxyCreator#createProxy(java.lang.Class, java.lang.String, java.lang.Object[], org.springframework.aop.TargetSource)}
	 * 			中的522行通过对Bean的判断进行赋值,默认为false
	 * 		2、可指定org.springframework.context.annotation.EnableAspectJAutoProxy注解中的proxyTargetClass属性
	 *
	 * 判断是否只指定了{@link org.springframework.aop.SpringProxy}接口
	 */
	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.");
		}
		/**
		 * 如果目标类是一个接口(指的是本身是一个接口,而不是实现接口)
		 * 或者实现了Proxy类
		 * 则还是使用JDK代理
		 * 否则使用CGLIB代理
		 */
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

/**
 * Determine whether the supplied {@link AdvisedSupport} has only the
 * {@link org.springframework.aop.SpringProxy} interface specified
 * (or no proxy interfaces specified at all).
 */
/**
 * 确定提供的{@link AdvisedSupport}是否只指定了{@link org.springframework.aop.SpringProxy}接口
 * (或者根本没有指定代理接口)
 */
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
	Class<?>[] ifcs = config.getProxiedInterfaces();
	return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
CglibAopProxy#getProxy()
/**
 * 使用CGLIB代理,需要了解CGLIB相关知识
 * 获得并返回代理对象
 */
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
	}

	try {
		/**
		 * 获得需要代理的Class
		 */
		Class<?> rootClass = this.advised.getTargetClass();
		Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

		Class<?> proxySuperClass = rootClass;
		/**
		 * 判断需要被代理的Class是否已经被CGLIB代理过了
		 * 已经被代理过了则进入if代码块处理一下
		 * 获取此类的父类,CGLIB是基于继承来的,所以获取父类就是获取原始类
		 * 再获取所有继承的接口,存储起来
		 */
		if (ClassUtils.isCglibProxyClass(rootClass)) {
			proxySuperClass = rootClass.getSuperclass();
			Class<?>[] additionalInterfaces = rootClass.getInterfaces();
			for (Class<?> additionalInterface : additionalInterfaces) {
				this.advised.addInterface(additionalInterface);
			}
		}

		// Validate the class, writing log messages as necessary.
		/**
		 * 验证类,提出建议,下面两种情况可能会对代理产生干扰,具体代码自行查看
		 * 	1. 对final修饰的方法
		 * 	2. 被代理类的ClassLoader和即将使用的ClassLoader不同
		 */
		validateClassIfNecessary(proxySuperClass, classLoader);

		// Configure CGLIB Enhancer.....0.
		/**
		 * 以下为CGLIB代理的相关知识,这里不过多解释,其实对CGLIB代理最重要的就是
		 * Filter,这些Filter较难理解,暂时没有太深入研究,待研究之后会对文章做更新
		 */
		Enhancer enhancer = createEnhancer();
		if (classLoader != null) {
			enhancer.setClassLoader(classLoader);
			if (classLoader instanceof SmartClassLoader &&
					((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
				enhancer.setUseCache(false);
			}
		}
		enhancer.setSuperclass(proxySuperClass);
		enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

		/**
		 * 获取使用的Filter
		 */
		Callback[] callbacks = getCallbacks(rootClass);
		Class<?>[] types = new Class<?>[callbacks.length];
		for (int x = 0; x < types.length; x++) {
			types[x] = callbacks[x].getClass();
		}
		// fixedInterceptorMap only populated at this point, after getCallbacks call above
		enhancer.setCallbackFilter(new ProxyCallbackFilter(
				this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
		enhancer.setCallbackTypes(types);

		// Generate the proxy class and create a proxy instance.
		return createProxyClassAndInstance(enhancer, callbacks);
	}
	catch (CodeGenerationException | IllegalArgumentException ex) {
		throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
				": Common causes of this problem include using a final class or a non-visible class",
				ex);
	}
	catch (Throwable ex) {
		// TargetSource.getTarget() failed
		throw new AopConfigException("Unexpected AOP exception", ex);
	}
}
JdkDynamicAopProxy#getProxy()
/**
 * 使用JDK代理返回代理对象
 */
@Override
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);
	/**
	 * 判断接口中是否重写了equals和hashCode方法
	 */
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
	/**
	 * 使用JDK生成代理对象
	 * 第一个参数是类加载器
	 * 第二个参数是代理类需要实现的接口,即目标类实现的接口
	 * 第三个是InvocationHandler,本类实现了此接口
	 */
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
AopProxyUtils#completeProxiedInterfaces()
/**
 * 获取需要代理的接口
 */
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
	/**
	 * 获取配置中存在的需要代理的接口
	 */
	Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
	/**
	 * 配置中不存在需要代理的接口执行以下逻辑
	 */
	if (specifiedInterfaces.length == 0) {
		// No user-specified interfaces: check whether target class is an interface.
		/**
		 * 获取目标对象
		 */
		Class<?> targetClass = advised.getTargetClass();
		if (targetClass != null) {
			/**
			 * 目标对象是一个接口则直接配置到配置对象中
			 */
			if (targetClass.isInterface()) {
				advised.setInterfaces(targetClass);
			}
			/**
			 * 目标对象实现了Proxy接口
			 */
			else if (Proxy.isProxyClass(targetClass)) {
				advised.setInterfaces(targetClass.getInterfaces());
			}
			specifiedInterfaces = advised.getProxiedInterfaces();
		}
	}
	/**
	 * 是否新增SpringProxy,在AdvisedSupport#isInterfaceProxied方法中会判断传入的接口是否已经由目标对象实现。
	 * 此处传入SpringProxy.class判断目标对象是否已经实现该接口,如果没有实现则在代理对象中需要新增SpringProxy,
	 * 如果实现了则不必新增
	 */
	boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
	/**
	 * 是否新增Adviced接口,注意不是Advice通知接口。
	 * ProxyConfig#isOpaque方法用于返回由这个配置创建的代理对象是否应该避免被强制转换为Advised类型。
	 * 还有一个条件和上面的方法一样,同理,传入Advised.class判断目标对象是否已经实现该接口,
	 * 如果没有实现则在代理对象中需要新增Advised,如果实现了则不必新增。
	 */
	boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
	/**
	 * 是否新增DecoratingProxy接口,同样的判断条件有两个:
	 * 第一个参数decoratingProxy,在调用completeProxiedInterfaces方法时传入的是true,
	 * 第二个判断条件和上面一样判断被代理的目标对象是否已经实现了DecoratingProxy接口。
	 * 通常情况下这个接口也会被加入到代理对象中。
	 */
	boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
	/**
	 * 通过以下的判断,获取新增的接口的数量
	 */
	int nonUserIfcCount = 0;
	if (addSpringProxy) {
		nonUserIfcCount++;
	}
	if (addAdvised) {
		nonUserIfcCount++;
	}
	if (addDecoratingProxy) {
		nonUserIfcCount++;
	}
	/**
	 * 根据新增接口的数量和原接口的数量重新定义数组
	 * 并向数组中追加原数组的数据
	 */
	Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
	System.arraycopy(specifiedInterfaces, 0, proxiedInterfaces, 0, specifiedInterfaces.length);
	/**
	 * 增加目标类没有实现的接口
	 */
	int index = specifiedInterfaces.length;
	if (addSpringProxy) {
		proxiedInterfaces[index] = SpringProxy.class;
		index++;
	}
	if (addAdvised) {
		proxiedInterfaces[index] = Advised.class;
		index++;
	}
	if (addDecoratingProxy) {
		proxiedInterfaces[index] = DecoratingProxy.class;
	}
	/**
	 * 返回
	 */
	return proxiedInterfaces;
}
JdkDynamicAopProxy#findDefinedEqualsAndHashCodeMethods()
/**
 * 判断这些类中是否重写了Object的equals方法和hashCode方法
 *
 * 如果目标对象直接重写Object对象的equals或hashCode方法,此时Spring AOP则不会对它增强,
 * equalsDefined=false或hashCodeDefined=false;如果目标对象实现的接口定义了equals或hashCode方法,
 * 此时Spring AOP则会对它增强,equalsDefined=true或hashCodeDefined=true。
 * 所以“通常情况”就是我们并不会在接口定义equals或hashCode方法,
 * “不通常情况”就是在有的特殊情况下在接口定义equals或hashCode方法。
 * 再换句话说,如果我们需要Spring AOP增强equals或hashCode方法则必须
 * 要在其目标对象的实现接口定义equals或hashCode方法。
 */
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
	for (Class<?> proxiedInterface : proxiedInterfaces) {
		Method[] methods = proxiedInterface.getDeclaredMethods();
		for (Method method : methods) {
			if (AopUtils.isEqualsMethod(method)) {
				this.equalsDefined = true;
			}
			if (AopUtils.isHashCodeMethod(method)) {
				this.hashCodeDefined = true;
			}
			if (this.equalsDefined && this.hashCodeDefined) {
				return;
			}
		}
	}
}
JdkDynamicAopProxy#invoke()
/**
 * JDK代理的钩子函数
 * 第一个参数是目标对象
 * 第二个参数是目标方法
 * 第三个参数是目标方法的参数
 */
@Override
@Nullable
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 {
		/**
		 * 方法是目标对象的equals方法,且接口中未定义equals方法,则直接执行equals方法,不进行代理
		 */
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// The target does not implement the equals(Object) method itself.
			return equals(args[0]);
		}

		/**
		 * hashCode方法同equals方法一样,不进行代理
		 */
		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);
		}
		/**
		 * Spring AOP不会增强直接实现Advised接口的目标对象
		 * 如果目标对象实现的Advised接口,则不会对其应用切面进行方法的增强
		 */
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
				method.getDeclaringClass().isAssignableFrom(Advised.class)) {
			// Service invocations on ProxyConfig with the proxy config...
			/**
			 * 这个方法里面就是直接调用method.invoke()直接执行目标方法
			 */
			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}

		/**
		 * 返回值
		 */
		Object retVal;

		/**
		 * 是否暴露代理对象,默认false可配置为true,如果暴露就意味着允许在线程内共享代理对象,
		 * 注意这是在线程内,也就是说同一线程的任意地方都能通过AopContext获取该代理对象,
		 * 这应该算是比较高级一点的用法了
		 */
		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.
		/**
		 * 获取目标对象和目标对象的Class
		 */
		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);

		// Get the interception chain for this method.
		/**
		 * 获取拦截器链
		 */
		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.
		/**
		 * 如果拦截器链为空的话就直接调用目标对象方法
		 */
		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);
		}
		/**
		 * 否则创建ReflectiveMethodInvocation对象完成对AOP功能实现的封装
		 * 并调用方法生成返回值
		 */
		else {
			// We need to create a method invocation...
			invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
			// Proceed to the joinpoint through the interceptor chain.
			/**
			 * @see ReflectiveMethodInvocation#proceed()
			 */
			retVal = invocation.proceed();
		}

		// Massage return value if necessary.
		/**
		 * 获取目标方法的返回值
		 */
		Class<?> returnType = method.getReturnType();
		/**
		 * 符合以下条件则代理逻辑失效,不对其进行代理
		 * 返回值不是null
		 * 返回值等于目标对象
		 * 返回值不是Object类型
		 * 目标方法的返回值是目标对象
		 * 目标对象不是RawTargetAccess借口实例
		 */
		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;
		}
		/**
		 * 符合以下条件报错
		 * 返回值为null
		 * 目标方法的返回值类型不是void
		 * 目标方法的返回值类型是基础类型封装类
		 */
		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);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值