老生常谈系列之Aop--Spring Aop源码解析(二)
老生常谈系列之Aop--Spring Aop源码解析(二)
前言
上一篇文章老生常谈系列之Aop--Spring Aop源码解析(一)已经介绍完Spring Aop获取advice切面增强方法的逻辑,那这篇会介绍Spring Aop是怎么根据上面获取的advice生产动态代理的,并且会介绍advice是怎么执行的,例如怎么确保@Before的逻辑在@After前面执行。
源码分析
以下代码分析基于Spring版本5.2.x,另外部分地方我摘抄保留了英文注释,希望看官可以用心体会。
我们回到AbstractAutoProxyCreator#wrapIfNecessary()方法里,上面的部分已经分析完成,下面从Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean))开始。
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		// 省略部分逻辑...
		// 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;
	}
跟进createProxy()方法,对于代理类的创建及处理, Spring 委托给了 ProxyFactory去处理,而在此函数中主要是对 ProxyFactory的初始化操作,进而对真正的创建代理做准备。
	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);
		// 决定对于给定的 bean 是否应该使用 targetClass 而不是它的接口代理,
		// 检查 proxyTargetClass 设置以及 preserveTargetClass 属性
		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);
		// 用来控制代理工厂被配置之后,是否还允许修改通知
		// 缺省值为 false 即在代理被配置之后, 不允许修改代理的配置
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		return proxyFactory.getProxy(getProxyClassLoader());
	}
可以上到上面的准备工作包括了以下几步:
- 获取当前类中的属性。
 - 添加代理接口 。
 - 封装 Advisor 并加入到 ProxyFactory 中。
 - 设置要代理的类。
 - 当然在 Spring 中还为子类提供了定制的函数 customizeProxyFactory,子类可以在此函数中进行对 ProxyFactory的进一步封装。
 - 设置frozen和preFiltered
 - 进行获取代理操作。
 
其中,封装 Advisor 并加入到 ProxyFactory 中以及创建代理是两个相对繁琐的过程,可以通过ProxyFactory提供的 addAdvisor 方法直接将增强器置人代理创建工厂中,但是将拦截器封装为增强器还是需要一定的逻辑的。ProxyFactory类提供了非常好的一个抽象操作,addAdvisor 和getProxy()两个方法完成了我们所有的创建代理,里面隐藏了非常多的细节操作,那下面的分析会从准备工作的几步开始,分析每一步的代码做了什么。
1.获取当前类中的属性
这段逻辑只是简单的一句,入参为本身this,跟进copyFrom()方法。
proxyFactory.copyFrom(this);
可以看到只是简单的赋值操作,入参类型为ProxyConfig,由于AbstractAutoProxyCreator间接实现了ProxyConfig接口,这里只是把AbstractAutoProxyCreator里的几个属性赋值到接下来要使用的ProxyFactory 中。
	public void copyFrom(ProxyConfig other) {
		Assert.notNull(other, "Other ProxyConfig object must not be null");
		this.proxyTargetClass = other.proxyTargetClass;
		this.optimize = other.optimize;
		this.exposeProxy = other.exposeProxy;
		this.frozen = other.frozen;
		this.opaque = other.opaque;
	}
2.添加代理接口
添加属性完成后,接下来是根据proxyTargetClass属性设置ProxyFactory的proxyTargetClass属性和添加代理接口。这是个啥属性呢?没印象?那说明前面的文章根本没看。proxyTargetClass 定义是否强制使用CGLIB代理,默认是false,不使用。所以如果开了强制使用CGLIB的话,这段逻辑会被跳过,不会进行代理接口的添加。
		if (!proxyFactory.isProxyTargetClass()) {
                        // 是否基于类代理 preserveTargetClass = true 则是基于类代理
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				// 添加代理接口
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
如果proxyTargetClass = false的话,会进入这段逻辑。简单看一下shouldProxyTargetClass()代码,这里摘取了方法上的注解,可以品味一下。
	/**
	 * Determine whether the given bean should be proxied with its target class rather than its interfaces.
	 * <p>Checks the {@link AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute}
	 * of the corresponding bean definition.
	 * @param beanClass the class of the bean
	 * @param beanName the name of the bean
	 * @return whether the given bean should be proxied with its target class
	 * @see AutoProxyUtils#shouldProxyTargetClass
	 */
	protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) {
		return (this.beanFactory instanceof ConfigurableListableBeanFactory &&
				AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName));
	}
## AutoProxyUtils#shouldProxyTargetClass
	public static boolean shouldProxyTargetClass(
			ConfigurableListableBeanFactory beanFactory, @Nullable String beanName) {
		if (beanName != null && beanFactory.containsBeanDefinition(beanName)) {
			BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
			return Boolean.TRUE.equals(bd.getAttribute(PRESERVE_TARGET_CLASS_ATTRIBUTE));
		}
		return false;
	}
首先会通过shouldProxyTargetClass()判断是否基于类代理,这个方法是通过判断preserveTargetClass属性是否为true。如果是,则设置proxyTargetClass = true,看到这菊花一紧。preserveTargetClass的字面意思是保留目标类,摘取属性上的描述如下:
	/**
	 * Bean definition attribute that may indicate whether a given bean is supposed
	 * to be proxied with its target class (in case of it getting proxied in the first
	 * place). The value is {@code Boolean.TRUE} or {@code Boolean.FALSE}.
	 * <p>Proxy factories can set this attribute if they built a target class proxy
	 * for a specific bean, and want to enforce that bean can always be cast
	 * to its target class (even if AOP advices get applied through auto-proxying).
	 * @see #shouldProxyTargetClass
	 */
	public static final String PRESERVE_TARGET_CLASS_ATTRIBUTE =
			Conventions.getQualifiedAttributeName(AutoProxyUtils.class, "preserveTargetClass");
翻译一下:这是BeanDefinition定义的属性,它可以指示给定的 bean 是否应该与其目标类一起代理(以防它首先被代理)。该值为Boolean.TRUE 或 Boolean.FALSE。如果代理工厂为特定 bean 构建了目标类代理,并且希望强制该 bean 始终可以转换为其目标类(即使 AOP 建议通过自动代理应用),则可以设置此属性。
这一段翻译看完,应该就比较明了了。这是有特殊的要求希望代理类可以强制转换为目标类,可以设置这个属性。
举个例子如下,如果A和B是接口,C是实现类,那么走自动代理的时候会走JDK动态代理,代理会实现A、B接口,如果想把这个代理强制转换成C类型,可能会报错。这时候可以设置preserveTargetClass = true,直接代理目标类,这时候再转换,就不会出错。当然这是我猜测的原因,因为很少有人提及这个属性,我只是参考源码注释和实现给出的原因,错了轻拍。

以前只知道proxyTargetClass能够设置是否强制进行类代理,而不知道preserveTargetClass也能设置强制进行类代理。可能是由于这是BeanDefinition的属性,这是比注解上的属性更底层的属性,所以露面的机会少点。可能Spring不希望大部分人直接使用,但是如果要用,还是可以设置,相当于留了个后门。
如果没有设置preserveTargetClass,那么就进入evaluateProxyInterfaces(beanClass, proxyFactory)方法,添加代理接口。
	/**
	 * Check the interfaces on the given bean class and apply them to the {@link ProxyFactory},
	 * if appropriate.
	 * <p>Calls {@link #isConfigurationCallbackInterface} and {@link #isInternalLanguageInterface}
	 * to filter for reasonable proxy interfaces, falling back to a target-class proxy otherwise.
	 * @param beanClass the class of the bean
	 * @param proxyFactory the ProxyFactory for the bean
	 */
	protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
		Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
                // 是否存在符合条件的接口
		boolean hasReasonableProxyInterface = false;
		for (Class<?> ifc : targetInterfaces) {
			if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
					ifc.getMethods().length > 0) {
				hasReasonableProxyInterface = true;
				break;
			}
		}
		if (hasReasonableProxyInterface) {
			// Must allow for introductions; can't just set interfaces to the target's interfaces only.
                        // 加入接口,同时要允许introductions也能加入接口,不能仅仅设置当前类的接口,introductions类型的接口什么时候加入,下面第三点会说到
			for (Class<?> ifc : targetInterfaces) {
				proxyFactory.addInterface(ifc);
			}
		}
		else {
			proxyFactory.setProxyTargetClass(true);
		}
	}
这段逻辑也简单明了,获取beanClass的所有接口,判断这些接口是否值得代理。如果有hasReasonableProxyInterface = true,就通过proxyFactory.addInterface(ifc)加入到this.interfaces里,随后通过adviceChanged()刷新缓存。
3.封装 Advisor 并加入到 ProxyFactory 中
封装Advisor
设置完相关属性后,这里才进入正题,开始封装Advisor ,并加入到ProxyFactory 中。
	/**
	 * Determine the advisors for the given bean, including the specific interceptors
	 * as well as the common interceptor, all adapted to the Advisor interface.
	 * @param beanName the name of the bean
	 * @param specificInterceptors the set of interceptors that is
	 * specific to this bean (may be empty, but not null)
	 * @return the list of Advisors for the given bean
	 */
	protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
		// Handle prototypes correctly...
		// 解析通用的拦截器interceptorNames,interceptorNames是通过setInterceptorNames()设置的
		Advisor[] commonInterceptors = resolveInterceptorNames();
		List<Object> allInterceptors = new ArrayList<>();
		if (specificInterceptors != null) {
			// 加入指定的拦截器
			allInterceptors.addAll(Arrays.asList(specificInterceptors));
                        // 如果有通用拦截器,加入通用的拦截器,通常情况下commonInterceptors.length=0
			if (commonInterceptors.length > 0) {
                                // 如果是先应用通用拦截器,则加到前面,否则加到后面
				if (this.applyCommonInterceptorsFirst) {
					allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
				}
				else {
					allInterceptors.addAll(Arrays.asList(commonInterceptors));
				}
			}
		}
		// 省略日志...
		Advisor[] advisors = new Advisor[allInterceptors.size()];
		for (int i = 0; i < allInterceptors.size(); i++) {
			// 对拦截然进行封装转化为 Advisor
			advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
		}
		return advisors;
	}
这段代码的逻辑主要分为两部分:
- 将获取到的通用拦截器
commonInterceptors和方法传入的specificInterceptors加入到allInterceptors里 - 对
allInterceptors进行封装,返回advisors 
首先看第一部分,跟进resolveInterceptorNames()方法。
	/**
	 * Resolves the specified interceptor names to Advisor objects.
	 * @see #setInterceptorNames
	 */
	private Advisor[] resolveInterceptorNames() {
		BeanFactory bf = this.beanFactory;
		ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
		List<Advisor> advisors = new ArrayList<>();
		for (String beanName : this.interceptorNames) {
			if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
				Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
				Object next = bf.getBean(beanName);
				advisors.add(this.advisorAdapterRegistry.wrap(next));
			}
		}
		return advisors.toArray(new Advisor[0]);
	}
主要是对interceptorNames属性进行遍历,根据beanName到容器中获取这个bean,然后封装成advisors返回。
那这个interceptorNames是个啥呢?这就是通用拦截器的名字,默认是空。可以通过调用setInterceptorNames()方法设置,搜索了一下Spring里调用这个方法的地方,发现没有,所以这个地方默认就是空的,可以是看做Spring留了个扩展点。
	/** Default is no common interceptors. */
	private String[] interceptorNames = new String[0];
	/**
	 * Set the common interceptors. These must be bean names in the current factory.
	 * They can be of any advice or advisor type Spring supports.
	 * <p>If this property isn't set, there will be zero common interceptors.
	 * This is perfectly valid, if "specific" interceptors such as matching
	 * Advisors are all we want.
	 */
	public void setInterceptorNames(String... interceptorNames) {
		this.interceptorNames = interceptorNames;
	}
处理完了通用拦截器部分,接下来直接把specificInterceptors加入到allInterceptors里。通常情况下,可以认为allInterceptors的内容就是传进来的specificInterceptors。
到这里处理完了第一部分获取allInterceptors,接下来是第二部分对allInterceptors进行封装,返回advisors。
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
这一部分委托给了DefaultAdvisorAdapterRegistry#wrap()去实现,直接跟进代码,这里比较简单,只是简单封装为Advisor。
	public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
		// 如果要封装的对象本身就是 Advisor类型的,那么无须再做过多处理
		if (adviceObject instanceof Advisor) {
			return (Advisor) adviceObject;
		}
		// 因为此封装方法只对 Advisor 与 Advice 两种类型的数据有效, 如果不是将不能封装
		if (!(adviceObject instanceof Advice)) {
			throw new UnknownAdviceTypeException(adviceObject);
		}
		Advice advice = (Advice) adviceObject;
		if (advice instanceof MethodInterceptor) {
			// So well-known it doesn't even need an adapter.
			// 如果是 MethodInterceptor 类型则使用 DefaultPointcutAdvisor 封装
			return new DefaultPointcutAdvisor(advice);
		}
		// 如果存在 Advisor 的适配器那么也同样需要进行封装
		for (AdvisorAdapter adapter : this.adapters) {
			// Check that it is supported.
			if (adapter.supportsAdvice(advice)) {
				return new DefaultPointcutAdvisor(advice);
			}
		}
		throw new UnknownAdviceTypeException(advice);
	}
到这里已经把所有的拦截器转换成统一的Advisor,下面就准备设置进ProxyFactory 里。
将Advisor加入ProxyFactory
一行代码,跟进addAdvisors()
proxyFactory.addAdvisors(advisors);
可以看到也是简单的赋值操作,把入参的advisors赋值到this.advisors,注意这里有个特殊操作validateIntroductionAdvisor(),这是用来处理IntroductionAdvisor类型的Advisor,核心操作就是校验IntroductionAdvisor的接口,如果符合,那就加入到this.interfaces里,这跟上面添加代理接口evaluateProxyInterfaces(beanClass, proxyFactory)逻辑是类似的。最后会更新this.advisorArray和this.methodCache,这两个缓存主要用于内部操作,节省时间。
	/**
	 * Add all of the given advisors to this proxy configuration.
	 * @param advisors the advisors to register
	 */
	public void addAdvisors(Advisor... advisors) {
		addAdvisors(Arrays.asList(advisors));
	}
	/**
	 * Add all of the given advisors to this proxy configuration.
	 * @param advisors the advisors to register
	 */
	public void addAdvisors(Collection<Advisor> advisors) {
		if (isFrozen()) {
			throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
		}
		if (!CollectionUtils.isEmpty(advisors)) {
			for (Advisor advisor : advisors) {
				if (advisor instanceof IntroductionAdvisor) {
					validateIntroductionAdvisor((IntroductionAdvisor) advisor);
				}
				Assert.notNull(advisor, "Advisor must not be null");
				this.advisors.add(advisor);
			}
                        // 更新this.advisorArray
			updateAdvisorArray();
                        // 更新this.methodCache
			adviceChanged();
		}
	}
4.设置要代理的类
这一步也比较简单,把传入的targetSource设置到proxyFactory中,如果为空,则将targetSource设为EMPTY_TARGET_SOURCE。EMPTY_TARGET_SOURCE是一个特殊的TargetSource它是在没有目标类或者只有advisors或者interfaces的时候使用。
	public void setTargetSource(@Nullable TargetSource targetSource) {
		this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE);
	}
5.定制的函数 customizeProxyFactory
目前是个空实现,交由子类实现,提供了自定义扩展的点。
	customizeProxyFactory(proxyFactory);
AbstractAutoProxyCreator中的实现为空。
	/**
	 * Subclasses may choose to implement this: for example,
	 * to change the interfaces exposed.
	 * <p>The default implementation is empty.
	 * @param proxyFactory a ProxyFactory that is already configured with
	 * TargetSource and interfaces and will be used to create the proxy
	 * immediately after this method returns
	 */
	protected void customizeProxyFactory(ProxyFactory proxyFactory) {
	}
6.设置frozen和preFiltered
这里的代码也比较简单
		// 用来控制代理工厂被配置之后,是否还允许修改通知
		// 缺省值为 false 即在代理被配置之后, 不允许修改代理的配置 )
		proxyFactory.setFrozen(this.freezeProxy);
		// 是否已经被预过滤,如果是预过滤,可以不执行Pointcut持有的ClassFilter
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
frozen用来冻结advice的修改。这里主要是用来作为内部一些性能的优化,摘取描述如下:
	/**
	 * Set whether this config should be frozen.
	 * <p>When a config is frozen, no advice changes can be made. This is
	 * useful for optimization, and useful when we don't want callers to
	 * be able to manipulate configuration after casting to Advised.
	 */
	public void setFrozen(boolean frozen) {
		this.frozen = frozen;
	}
preFiltered可能相对难理解一点, 设置当前AOP配置信息是否已被超前过滤过了,如果是的话,可以不执行Pointcut持有的ClassFilter 。
	/**
	 * Set whether this proxy configuration is pre-filtered so that it only
	 * contains applicable advisors (matching this proxy's target class).
	 * <p>Default is "false". Set this to "true" if the advisors have been
	 * pre-filtered already, meaning that the ClassFilter check can be skipped
	 * when building the actual advisor chain for proxy invocations.
	 * @see org.springframework.aop.ClassFilter
	 */
	void setPreFiltered(boolean preFiltered);
7.进行获取代理操作
获取JDK动态代理或CGLIB代理
完成了上面的步骤之后,开始进入了本文章的重头戏,创建代理。
进入getProxy()方法,这里就会根据上面设置的属性生成代理对象,生成的对象会因为添加或删除interfaces和interceptors而不同。
	/**
	 * Create a new proxy according to the settings in this factory.
	 * <p>Can be called repeatedly. Effect will vary if we've added
	 * or removed interfaces. Can add and remove interceptors.
	 * <p>Uses the given class loader (if necessary for proxy creation).
	 * @param classLoader the class loader to create the proxy with
	 * (or {@code null} for the low-level proxy facility's default)
	 * @return the proxy object
	 */
	public Object getProxy(@Nullable ClassLoader classLoader) {
		/**
		 * 首先获取AopProxy对象,主要有两个实现JdkDynamicAopProxy和ObjenesisCglibAopProxy
		 * 分别用于jdk和Cglib动态代理生成,其getProxy()方法用于获取具体的代理类对象
		 */
		return createAopProxy().getProxy(classLoader);
	}
跟进createAopProxy(),如果this.active=false,首先调用activate()激活所有的AdvisedSupportListener,然后通过getAopProxyFactory()获取一个aopProxyFactory,再调用createAopProxy(this)获取AopProxy。
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}
getAopProxyFactory()用于获取aopProxyFactory,aopProxyFactory会在new ProxyFactory()的时候创建this.aopProxyFactory = new DefaultAopProxyFactory(),逻辑比较简单,这里不再分析。接下来看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.");
			}
			/**
			 * 如果要代理的类本身就是接口
			 * 或者它已经是个jdk的代理类(Proxy的子类,所有的jdk代理类都是此类的子类)
			 * 也会用jdk动态代理
			 */
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
                        // 返回一个CglibAopProxy
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			//如果有接口,就会跑到这个分支
			return new JdkDynamicAopProxy(config);
		}
	}
可以跟着注释看一下,这里决定了是使用JDK动态代理还是CGLIB代理。
JdkDynamicAopProxy实现
接下来就以JdkDynamicAopProxy为例,分析一下真正生成动态代理的getProxy()逻辑。
直接看代码
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
		}
		//获取完整的代理接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
                // 查找是否存在equals()和hashCode()方法
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
                // 调用JDK动态代理的API生成代理
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
这里的逻辑也简单明了,先获取最终的完整的代理接口,查找是否存在equals()和hashCode()方法,最后调用Proxy.newProxyInstance()生成动态代理。
先来看获取完整代理接口的方法AopProxyUtils.completeProxiedInterfaces(this.advised, true)。这个方法先获取了指定的代理接口,然后获取SpringProxy、Advised和DecoratingProxy三个接口,最后返回proxiedInterfaces。
	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.
                        // 没有指定的代理接口,检查target class 是不是接口或者是不是Proxy的子类
			Class<?> targetClass = advised.getTargetClass();
			if (targetClass != null) {
				if (targetClass.isInterface()) {
					advised.setInterfaces(targetClass);
				}
				else if (Proxy.isProxyClass(targetClass)) {
					advised.setInterfaces(targetClass.getInterfaces());
				}
				specifiedInterfaces = advised.getProxiedInterfaces();
			}
		}
                // 判断是否加入这几个接口
		boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
		boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
		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;
	}
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces)比较简单,这里不贴代码了。
Proxy.newProxyInstance(),这里把代码贴出来,但是不做分析,详细原理看老生常谈系列之Aop--JDK动态代理的底层实现原理。
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {
        Objects.requireNonNull(h);
        final Class<?>[] intfs = interfaces.clone();
        final SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
        }
        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);
        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }
            final Constructor<?> cons = cl.getConstructor(constructorParams);
            final InvocationHandler ih = h;
            if (!Modifier.isPublic(cl.getModifiers())) {
                AccessController.doPrivileged(new PrivilegedAction<Void>() {
                    public Void run() {
                        cons.setAccessible(true);
                        return null;
                    }
                });
            }
            return cons.newInstance(new Object[]{h});
        } catch (IllegalAccessException|InstantiationException e) {
            throw new InternalError(e.toString(), e);
        } catch (InvocationTargetException e) {
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            } else {
                throw new InternalError(t.toString(), t);
            }
        } catch (NoSuchMethodException e) {
            throw new InternalError(e.toString(), e);
        }
    }
CglibAopProxy实现
直接来看getProxy()方法,会比JDK动态代理的复杂一奈奈。
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
		}
		try {
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
			Class<?> proxySuperClass = rootClass;
                        // 先获取rootClass,如果rootClass的name包含$$,继续获取它的父类,随后获取rootClass父类的接口,加入advised
			if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
				proxySuperClass = rootClass.getSuperclass();
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}
			// Validate the class, writing log messages as necessary.
                        // 校验class
			validateClassIfNecessary(proxySuperClass, classLoader);
			// Configure CGLIB Enhancer...
                        // 使用Enhancer增强
			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 ClassLoaderAwareGeneratorStrategy(classLoader));
			// 重点关注:设置拦截器
			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
                        // 重点关注:设置CallbackFilter
			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);
		}
		// 省略异常捕获
	}
我们看重点方法,主要有getCallbacks()和createProxyClassAndInstance(enhancer, callbacks)。
来看一下getCallbacks()代码,方法虽长,但是很常规。就是获取主要的Callback,然后根据isStatic和isFrozen进行优化,优化的方法很简单,就是获取rootClass的所有方法rootClass.getMethods(),然后加入到最后要返回的callbacks里。
	private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
		// Parameters used for optimization choices...
		// 对于 expose-proxy 属性的处理
		boolean exposeProxy = this.advised.isExposeProxy();
		boolean isFrozen = this.advised.isFrozen();
		boolean isStatic = this.advised.getTargetSource().isStatic();
                // 这一部分为获取Callback
		// Choose an "aop" interceptor (used for AOP calls).
		// 将拦截器封装在 DynamicAdvisedInterceptor中
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
		// Choose a "straight to target" interceptor. (used for calls that are
		// unadvised but can return this). May be required to expose the proxy.
		Callback targetInterceptor;
		if (exposeProxy) {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
		}
		else {
			targetInterceptor = (isStatic ?
					new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
					new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
		}
		// Choose a "direct to target" dispatcher (used for
		// unadvised calls to static targets that cannot return this).
		Callback targetDispatcher = (isStatic ?
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
		Callback[] mainCallbacks = new Callback[] {
				// 将拦截器链加入 Callback中
				aopInterceptor,  // for normal advice
				targetInterceptor,  // invoke target without considering advice, if optimized
				new SerializableNoOp(),  // no override for methods mapped to this
				targetDispatcher, this.advisedDispatcher,
				new EqualsInterceptor(this.advised),
				new HashCodeInterceptor(this.advised)
		};
                // 这一部分为优化
		Callback[] callbacks;
		// If the target is a static one and the advice chain is frozen,
		// then we can make some optimizations by sending the AOP calls
		// direct to the target using the fixed chain for that method.
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = new HashMap<>(methods.length);
			// TODO: small memory optimization here (can skip creation for methods with no advice)
			for (int x = 0; x < methods.length; x++) {
				Method method = methods[x];
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
				fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
						chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
				this.fixedInterceptorMap.put(method, x);
			}
			// Now copy both the callbacks from mainCallbacks
			// and fixedCallbacks into the callbacks array.
			callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
			System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
			System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
			this.fixedInterceptorOffset = mainCallbacks.length;
		}
		else {
			callbacks = mainCallbacks;
		}
		return callbacks;
	}
获取了Callbacks,接下来就是调用createProxyClassAndInstance(enhancer, callbacks)生成代理了。
	protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
		enhancer.setInterceptDuringConstruction(false);
		enhancer.setCallbacks(callbacks);
		return (this.constructorArgs != null && this.constructorArgTypes != null ?
				enhancer.create(this.constructorArgTypes, this.constructorArgs) :
				enhancer.create());
	}
到这里已经可以通过enhancer.create()生成一个动态代理,这一块讲得比较简单,Spring Aop对Enhancer的配置基本被略过,Enhancer的原理如同JDK动态代理的原理一样,也都略过。主要是限于篇幅,再写下去就会非常冗长。具体原理可以看补充文章老生常谈系列之Aop--CGLIB动态代理的底层实现原理。
拦截器的执行顺序
切面增强方法获取到了,代理也生成了,那么在执行的时候,是怎么保证顺序的呢?@Before如何保证在@After前执行,从始至终我们看到,Spring Aop没有对切面进行任何的分类或许排序去保证执行顺序,那么这个顺序怎么保证呢?
其实这个由拦截器本身的实现来完成了。在方法执行的时候,如果有多个切面方法,那么这些会被组装成一个拦截链去执行。看到这里是不是更迷惑了,一个拦截链,又没有顺序,执行过去不就全乱了吗?其实不是的,我们来看一下代码的实现,这里摘取MethodBeforeAdviceInterceptor和AspectJAfterAdvice的invoke()方法实现就一目了然了。
MethodBeforeAdviceInterceptor#invoke()代码
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
                // 先执行切面增强方法
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
                // 再执行下一个
		return mi.proceed();
	}
AspectJAfterAdvice#invoke()代码
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
                        // 直接执行下一个,处理完成返回后再执行切面增强方法
			return mi.proceed();
		}
		finally {
                        // 后执行切面增强方法
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
看到这里应该已经明白为啥顺序能保证了,Spring Aop这里是比较巧妙地利用了方法的执行位置来完成这个顺序的保证,简单明了,还不需要对增强方法进行排序分类执行。
总结
这一篇主要分析了Spring Aop生成动态代理的准备工作,以及JDK动态代理和CGLIB动态代理的过程。当然这里只是简单的跟着注释走马观花看了一下Spring Aop生成动态代理的逻辑,还是比较简单的。至此,Spring Aop部分的逻辑已经走完,接下来的原理就是JDK动态代理和CGLIB动态代理的生成原理。这一部分涉及的就是JVM的反射和字节码修改等操作,欲知后事如何,且听下回分解。
如果有人看到这里,那在这里老话重提。与君共勉,路漫漫其修远兮,吾将上下而求索。
老生常谈系列之Aop--Spring Aop源码解析(二)的更多相关文章
- Spring系列(三):Spring IoC源码解析
		
一.Spring容器类继承图 二.容器前期准备 IoC源码解析入口: /** * @desc: ioc原理解析 启动 * @author: toby * @date: 2019/7/22 22:20 ...
 - Spring Boot系列(四):Spring Boot源码解析
		
一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...
 - Spring IoC源码解析之getBean
		
一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...
 - spring事务源码解析
		
前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...
 - Spring IoC源码解析之invokeBeanFactoryPostProcessors
		
一.Bean工厂的后置处理器 Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistr ...
 - Feign 系列(04)Contract 源码解析
		
Feign 系列(04)Contract 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/11563952.html# ...
 - Spring Security源码解析一:UsernamePasswordAuthenticationFilter之登录流程
		
一.前言 spring security安全框架作为spring系列组件中的一个,被广泛的运用在各项目中,那么spring security在程序中的工作流程是个什么样的呢,它是如何进行一系列的鉴权和 ...
 - Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例
		
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
 - Java 集合系列 10 Hashtable详细介绍(源码解析)和使用示例
		
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
 - Java 集合系列 06 Stack详细介绍(源码解析)和使用示例
		
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
 
随机推荐
- 在 Java 中 Executor 和 Executors 的区别?
			
Executors 工具类的不同方法按照我们的需求创建了不同的线程池,来满足业务 的需求. Executor 接口对象能执行我们的线程任务. ExecutorService 接口继承了 Executo ...
 - springboot项目如何添加热部署
			
环境jdk1.8.maven3.6.使用工具为idea 1.在pom.xml文件中添加依赖 <dependency> <groupId>org.springframework. ...
 - Spark学习摘记 —— RDD行动操作API归纳
			
本文参考 参考<Spark快速大数据分析>动物书中的第三章"RDD编程",前一篇文章已经概述了转化操作相关的API,本文再介绍行动操作API 和转化操作API不同的是, ...
 - C++函数声明的时候后面加const
			
非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误),表示成员函数隐含传入的this指针为const指针,决定了在该成员函数中,任意修改该类中成员的操作都是不允许的(因为隐含了 ...
 - ROS终端中创建功能包的常用命令
 - 写了一个web os脚手架
			
预览地址在这里:http://thx.github.io/magix-os/项目地址在这里:https://github.com/thx/magix-os 介绍下目录结构 核心目录cores主要是构成 ...
 - tf.test.is_gpu_available() 返回结果为False解决办法
			
安装完gpu版本的tensorflow,导入正常,但是tf.test.is_gpu_available()一直返回False,解决办法: 1.打开NVIDIA控制面板,查看CUDA的驱动版本,如果版本 ...
 - Spring5-IOC底层原理
			
1.什么是IOC (1)控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理 (2)使用IOC目的:为了降低耦合度 2.IOC底层原理 (1)xml解析.工厂模式.反射
 - SpringMVC获取请求参数-基本类型
			
1.Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配 (json形式) <dependency> <groupId>com.faste ...
 - kubectl creat -f  创建pod时出错
			
如果创建yaml时候,sts中已经存在,但是get pod又查不到已经启动的pod可以这样 [root@k3master src]# kubectl get pod //查不到eureka NAME ...