Spring源码分析——AOP

Spring源码分析——AOP

寻找 aop:aspectj-autoproxy 注解对应的解析器

要使用SpringAop的功能,需要在XMl配置文件中配置 <aop:aspectj-autoproxy/>注解,这个注解便是开启spring的aop功能的开关,所以他就是分析aop功能原理的入口

org.springframework.aop.config.AopNamespaceHandler#init

	@Override
	public void init() {
		// In 2.0 XSD as well as in 2.5+ XSDs
		registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
		/**
		 * 注册自定义的BeanDefinition解析器,用于自定义 "节点解析成BeanDefinition" 的流程
		 * AspectJAutoProxyBeanDefinitionParser主要的功能就
		 * 是将AnnotationAwareAspectJAutoProxyCreator注册到Spring容器中,
		 * 把bean交给Spring去托管
		 */
		registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
		registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

		// Only in 2.0 XSD: moved to context namespace in 2.5+
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
	}

可以看到,我们只要配置了<aop:aspectj-autoproxy/>注解,其实就会想spring容器中注册一个BeanDefinition解析器 AspectJAutoProxyBeanDefinitionParser,BeanDefinition解析器的功能就是想spring容器中解析注册BeanDefinition的,然后spring就会根据已有的BeanDefinition取实例化bean

了解AspectJAutoProxyBeanDefinitionParser对应的行为

org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser#parse

	@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		//注册 AnnotationAwareAspectJAutoProxyCreator 对应的的BeanDefinition
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		extendBeanDefinition(element, parserContext);
		return null;
	}

这里调用了AopNamespaceUtils的静态方法registerAspectJAnnotationAutoProxyCreatorIfNecessary

org.springframework.aop.config.AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary

	public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
		
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		registerComponentIfNecessary(beanDefinition, parserContext);
	}

可以看到,这里又接着调用另外一个静态方法的AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法

org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}

org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired

	@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;
		}

		/*创建AnnotationAwareAspectJAutoProxyCreator对应的BeanDefinition */
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		/*注册AnnotationAwareAspectJAutoProxyCreator对应的BeanDefinition*/
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

到这一步,就可以看到创建AnnotationAwareAspectJAutoProxyCreator对应的BeanDefinition并且注册该beanDefinition的处理,然后AnnotationAwareAspectJAutoProxyCreator的BeanDefinition就交给了spring容器管理了

分析AnnotationAwareAspectJAutoProxyCreator主要行为

AnnotationAwareAspectJAutoProxyCreator是AbstractAutoProxyCreator的子孙类,而AbstractAutoProxyCreator又实现了接口SmartInstantiationAwareBeanPostProcessor,
SmartInstantiationAwareBeanPostProcessor接口继承了InstantiationAwareBeanPostProcessor,而InstantiationAwareBeanPostProcessor又间接继承了BeanPostProcessor,所以可以认为AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor,因此它是一个bean后置处理器

而bean后置处理器的方法会在bean进行实例化回调的这个阶段被执行

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

	/**
	 * 如果bean被子类标识为要代理的bean,则使用配置的拦截器创建代理。
	 * 这个方法时重写BeanPostProcesser接口的方法
	 * 会在Bean完成初始化回调方法调用执行
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			/* 判断之前是否代理过 */
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				/* 在bean初始化之后对生产出的bean进行包装 */
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

postProcessAfterInitialization方法会在进行完bean的初始化回调方法后被执行,这里判断之前是否代理过,如果不是,就调用wrapIfNecessary进行代理

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

	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;
		}

		// 如果该类有advice则创建proxy.
		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;
	}

所以可以这么理解,一旦我们开启了aop的注解,那么在spring中创建的每个bean,在进行bean后置处理器的postProcessAfterInitialization回调的时候,都会被拿去校验是否方法作为作为joinPoint被某个切面的pointCut所切中,是的话就要进行代理返回代理对象。

创建proxy过程分析

上面如果判断要进行代理对象的创建时,就会通过createProxy创建代理对象,把该bean重新包装为代理对象proxy

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

	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);
		}
		// 1.创建proxyFactory,proxy的生产主要就是在proxyFactory做的
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		// 2.将当前bean适合的advice,重新封装下,封装为Advisor类,然后添加到ProxyFactory中
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		// 3.调用getProxy获取bean对应的proxy
		return proxyFactory.getProxy(getProxyClassLoader());
	}

上面方法主要分三步

  1. 创建proxyFactory,用于创建代理对象
  2. 将当前bean适合的advice封装为Advisor类,然后添加到ProxyFactory中
  3. 调用getProxy获取bean对应的proxy

org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)

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

org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy

	/**
	 * Subclasses should call this to get a new AOP proxy. They should <b>not</b>
	 * create an AOP proxy with {@code this} as an argument.
	 *
	 * createAopProxy()方法就是决定究竟创建何种类型的proxy JDKProxy or CGLIBProxy
	 */
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// 关键方法createAopProxy()
		return getAopProxyFactory().createAopProxy(this);
	}

createAopProxy就会进行创建代理类的工作,后面就会通过这个代理类获取代理对象

org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		// config.isOptimize()是否使用优化的代理策略,目前使用与CGLIB
		// config.isProxyTargetClass() 是否目标类本身被代理而不是目标类的接口
		// hasNoUserSuppliedProxyInterfaces()是否存在代理接口
		if (!IN_NATIVE_IMAGE &&
				(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)) {
				// 2.如果目标类是接口或者是代理类,则直接使用JDKproxy
				return new JdkDynamicAopProxy(config);
			}
			// 3.其他情况则使用CGLIBproxy
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

可以看到上面有两种情况

  • 如果要代理的对象是接口或者实现了某接口,则是由jdk动态代理
  • 普通类则使用CGLIB

我们看一下jdk动态代理的处理

JdkDynamicAopProxy.getProxy()方法

org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)

	@Override
	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);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		// JDK proxy 动态代理的标准用法
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

可以看到上面是jdk动态代理获取代理对象的标准用法

然后JdkDynamicAopProxy本身实现了Jdk动态代理要求实现的InvocationHandler
接口,所有肯定有Invoke方法

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

invoke()方法

以上的代码模式可以很明确的看出来,使用了JDK动态代理模式,真正的方法执行在invoke()方法里

org.springframework.aop.framework.JdkDynamicAopProxy#invoke

	@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;

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

		try {
			// 1.以下的几个判断,主要是为了判断method是否为equals、hashCode等Object的方法
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			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);
			}
			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);

			// 2.获取当前bean被拦截方法链表
			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.
			// 3.如果为空,则直接调用target的method
			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);
			}
			// 4.不为空,则逐一调用chain中的每一个拦截方法的proceed
			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);
			}
		}
	}

org.springframework.aop.framework.ReflectiveMethodInvocation#proceed

	@Override
	@Nullable
	public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
			if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

依次遍历拦截器链的每个元素,然后调用其实现,将真正调用工作委托给各个增强器

总结

所以当我们开启了Aop的注解以后,就会执行以下步骤

  1. AspectJAutoProxyBeanDefinitionParser 注册 AnnotationAwareAspectJAutoProxyCreator
  2. 再执行bean后置处理器的after方法回调时,判断该bean是否有advice
  3. 如果有则把bean包装为proxy对象返回
  4. 以后调用bean的方法时,通过proxy来调用,proxy依次调用增强器的相关方法,实现方法的切入
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值