Spring之AOP源码(二)

书接上文

文章目录

    • 一、简介
      • 1. 前文回顾
      • 2. 知识点补充
    • 二、ProxyFactory源码分析
      • 1. ProxyFactory
      • 2. JdkDynamicAopProxy
      • 3. ObjenesisCglibAopProxy
    • 三、 Spring AOP源码分析

一、简介

1. 前文回顾

前面我们已经介绍了AOP的基本使用方法以及基本原理,但是还没有涉及源码层面,这篇文章就深度分析一下SpringAOP的底层源码。

2. 知识点补充

  • TargetSource

在我们日常的AOP中,被代理对象就是Bean对象,是由BeanFactory给我们创建出来的,但是 Spring AOP中提供了TargetSource机制,可以让我们用来自定义逻辑来创建被代理对象。让我们通过一个简单的案例来说明如何使用 TargetSource。假设我们有一个服务类 UserService,它负责处理用户的业务逻辑,而我们希望在不同的场景下使用不同的实例。

定义目标类:

@Component
public class UserService {
    public void performAction() {
        System.out.println("Performing action in UserService");
    }
}

**自定义 TargetSource:**

@Component
public class CustomTargetSource implements TargetSource {

    @Override
    public Class<?> getTargetClass() {
        return UserService.class;
    }

    @Override
    public boolean isStatic() {
        return false;
    }

    @Override
    public Object getTarget() throws Exception {
        // 在此处根据业务逻辑返回不同的目标对象实例
        // 这里简单地返回一个新的 UserService 实例
        return new UserService();
    }

    @Override
    public void releaseTarget(Object target) throws Exception {
        // 可以在这里进行一些资源的释放操作
    }
}

配置切面:

@Aspect
@Component
public class CustomAspect {

    @Autowired
    private CustomTargetSource customTargetSource;

    @Before("execution(* com.zhouyu.service.UserService.*(..))")
    public void beforeUserServiceMethod() throws Exception {
        // 在方法执行前,使用 TargetSource 切换目标对象
        Object target = customTargetSource.getTarget();
        // 执行你的逻辑
    }
}

@Lazy注解生成代理对象的时候,底层就使用到了TargetSource

protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
		BeanFactory beanFactory = getBeanFactory();
		Assert.state(beanFactory instanceof DefaultListableBeanFactory,
				"BeanFactory needs to be a DefaultListableBeanFactory");
		final DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;

		TargetSource ts = new TargetSource() {
			@Override
			public Class<?> getTargetClass() {
				return descriptor.getDependencyType();
			}
			@Override
			public boolean isStatic() {
				return false;
			}
			@Override
			public Object getTarget() {
				Set<String> autowiredBeanNames = (beanName != null ? new LinkedHashSet<>(1) : null);
				Object target = dlbf.doResolveDependency(descriptor, beanName, autowiredBeanNames, null);
				if (target == null) {
					Class<?> type = getTargetClass();
					if (Map.class == type) {
						return Collections.emptyMap();
					}
					else if (List.class == type) {
						return Collections.emptyList();
					}
					else if (Set.class == type || Collection.class == type) {
						return Collections.emptySet();
					}
					throw new NoSuchBeanDefinitionException(descriptor.getResolvableType(),
							"Optional dependency not present for lazy injection point");
				}
				if (autowiredBeanNames != null) {
					for (String autowiredBeanName : autowiredBeanNames) {
						if (dlbf.containsBean(autowiredBeanName)) {
							dlbf.registerDependentBean(autowiredBeanName, beanName);
						}
					}
				}
				return target;
			}
			@Override
			public void releaseTarget(Object target) {
			}
		};

二、ProxyFactory源码分析

1. ProxyFactory

前面说过这个类是Spring底层对JDK以及Cglib动态代理的底层封装,下面我们分析一下这个类底层是怎么做的。

public static void main(String[] args) {
		UserService target = new UserService();
		//创建代理工厂
		ProxyFactory proxyFactory=new ProxyFactory();
		//设置代理对象
		proxyFactory.setTarget(target);
		//设置代理逻辑
		proxyFactory.addAdvice(new MethodBeforeAdvice() {
			@Override
			public void before(Method method, Object[] args, Object target) throws Throwable {
				System.out.println("before");
			}
		});
		//返回代理对象
		UserService proxy = (UserService) proxyFactory.getProxy();
		proxy.test();
	}

上面代码是我前面给出的一个案例,其中UserService proxy = (UserService) proxyFactory.getProxy();就返回了一个代理对象。进入proxyFactory.getProxy方法。

public Object getProxy() {
		return createAopProxy().getProxy();
	}

createAopProxy()就是用来创建AOP代理的,进入该方法。

protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// 默认为DefaultAopProxyFactory
		return getAopProxyFactory().createAopProxy(this);
	}

然后调用createAopProxy方法。

public interface AopProxyFactory {
	AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}

我们看AopProxyFactory的默认实现类DefaultAopProxyFactory是怎么实现该方法的。

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		// 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快
		// 或者isProxyTargetClass为true,
		// 或者被代理对象没有实现接口,
		// 或者只实现了SpringProxy这个接口
		// 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理

		// 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口

		// 是不是在GraalVM虚拟机上运行
		if (!NativeDetector.inNativeImage() &&
				(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动态代理还是cglib动态代理:

  • !NativeDetector.inNativeImage():如果当前的JVM是GraalVM那么就直接使用JDK动态代理
  • config.isOptimize():表示你是否需要优化(如果需要优化就会使用cglib),然后config就是ProxyFactory本身
  • config.isProxyTargetClass():表示代理的目标类是否时接口
  • hasNoUserSuppliedProxyInterfaces(config):判断ProxyFactory是否提供了接口setInterfaces,如果提供了这个就会返回false
  • if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) :首先判断被代理的类是否是一个接口,然后判断你现在代理的目标类,是否是jdk产生的代理类

通过上面方法createAopProxy()就返回了JdkDynamicAopProxyObjenesisCglibAopProxy这两个对象其中之一。然后,回到getProxy方法,它就会调用createAopProxy().getProxy();去生成正在的代理对象。

2. JdkDynamicAopProxy

通过上面代码如果我们最后决定使用的代理类是JdkDynamicAopProxy,那么就会由这个类生产代理对象。首先我们看看JDK是如何生成我们的代理对象的,关键是getProxy方法。

@Override
	public Object getProxy() {
		return getProxy(ClassUtils.getDefaultClassLoader());
	}

	@Override
	public Object getProxy(@Nullable ClassLoader classLoader) {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
		}
		// this实现了InvocationHandler
		return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
	}

很简单就是使用newProxyInstance创建了一个代理对象,this就实现了InvocationHandler。当我们执行代理对象的指定方法时,就会进入invoke方法,我们仔细分析一下这个方法底层:

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

		// 拿到被代理对象(targetSource) 
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			// 如果接口中没有定义equals()方法,那么则直接调用,不走代理
			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...
				// 也是直接调用Advised接口中的方法,不走代理逻辑
				// 其实就是利用代理对象获取ProxyFactory中的信息
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			// 如果ProxyFactory的exposeProxy为true,则将代理对象设置到currentProxy这个ThreadLocal中去,这样整个线程的执行过程中我们都可以拿到这个代理对象
			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.
			// 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成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.
			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.
				// 如果没有Advice,则直接调用对应方法
				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);
			}
		}
	}

我们知道在AOP中,我们执行指定方法时,这个方法可能会添加多个Advisor,组成一条链,在执行该方法的实际逻辑之前,首先需要执行完所有的Advisor逻辑。而生成这个链(本质上就是list集合)就是下面的代码:

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
		// 代理对象在执行某个方法时,会根据当前ProxyFactory中所设置的Advisor根据当前Method再次进行过滤

		MethodCacheKey cacheKey = new MethodCacheKey(method);

		// 注意这个List,表示的就是Advice链
		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(this, method, targetClass);,这里有一个点就是前面我们使用到的所有Advice,不管是前置通知还是后置通知或者是环绕通知,它们其实类时本质上都是MethodInterceptor类型。

@Override
	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.
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		// 从ProxyFactory中拿到所设置的Advice(添加时被封装成了DefaultPointcutAdvisor)
		// 添加的时候会控制顺序
		//取到当前所有的Advisor(切点+advice)
		//我们在使用porxyFacoty添加advice时会在底层转换为Advisor对象,切点默认是所有方法匹配
		Advisor[] advisors = config.getAdvisors();
		List<Object> interceptorList = new ArrayList<>(advisors.length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		Boolean hasIntroductions = null;
        //遍历当前proxyFactory所有的Advisor
		for (Advisor advisor : advisors) {
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				// 先匹配类
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {

					// 再匹配方法
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					boolean match;
					if (mm instanceof IntroductionAwareMethodMatcher) {
						if (hasIntroductions == null) {
							hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
						}
						match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
					}
					else {
						match = mm.matches(method, actualClass);
					}

					if (match) {
						// 如果匹配则将Advisor封装成为Interceptor,当前Advisor中的Advice可能即是MethodBeforeAdvice,也是ThrowsAdvice
						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
						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));
						}
					}

					// 最终,interceptorList中存储的是当前正在执行的Method所匹配的MethodInterceptor,可能动态的,也可能是非动态的,
					// 找到Method所匹配的MethodInterceptor后,就会开始调用这些MethodInterceptor,如果是动态的,会额外进行方法参数的匹配
				}
			}
			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 {
				// 将Advisor封装成为Interceptor
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

首先我们看下面这句代码

if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {

上面这句代码关键是通过pointcutAdvisor.getPointcut()获得当前的切点,然后调用切点的getClassFilter()获得要拦截的目标类,然后判断是否和当前类actualClass匹配,一句话说就是上面if就是判断类型匹配的。如果类型匹配后就会开始匹配方法:

MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
	if (hasIntroductions == null) {
		hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
	}
	match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
	}
	else {
		match = mm.matches(method, actualClass);
   }

关键是调用match = mm.matches(method, actualClass);这句代码判断当前的方法和要拦截的方法是否匹配。如果前面两个条件都符合,就会执行下面的逻辑:

if (match) {
	   // 如果匹配则将Advisor里面的advice封装成为Interceptor,当前Advisor中的Advice可能即是MethodBeforeAdvice,也是ThrowsAdvice
		MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
		//如果方法匹配起的isRuntime属性是true
		if (mm.isRuntime()) {
				for (MethodInterceptor interceptor : interceptors) {
					interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
				}
		}
		else {
				interceptorList.addAll(Arrays.asList(interceptors));
		}
}

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);首先将当前的Advisor转换为一个MethodInterceptor对象。然后它会判断你是否设置了方法匹配器的isRuntime是否为true,为true就会对MethodInterceptor进行二次封装,这么做的目的就是为了处理如果我们调用的目标类的目标方法有参数,我们还要考虑参数匹配的情况,会被封装到InterceptorAndDynamicMethodMatcher这个MethodInterceptor对象中。

@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		//拿到当前advisor的advice对象
		Advice advice = advisor.getAdvice();
		//如果当前的advice本来就是MethodInterceptor类型,直接加入数组中
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		// 将Advice适配成MethodInterceptor
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(new MethodInterceptor[0]);
	}

上面源码其实就是将一个Advisor中的所有Advice封装到MethodInterceptor[]数组中,如果某个Advice类型是MethodInterceptor,那它就可以直接被添加到这个数组中,否则就要通过下面代码进行适配:

for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);


	/**
	 * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
	 */
	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}

可以看出适配器有三种,分别是MethodBeforeAdviceAdapterAfterReturningAdviceAdapterThrowsAdviceAdapter,分别对应前面说到的前置、后置和异常通知。然后调用adapter.supportsAdvice(advice),使用适配器supportsAdvice,判断当前的Advice是否适配。

在这里插入图片描述
可以看出每个适配器都实现了该方法,我们随便拿出其中一个,看看是如何适配的。

@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof AfterReturningAdvice);
	}

可以发现直接就是instanceof进行类型判断。进行类型判断后,如果符合,现在就是需要将当前的Advice类型转换为MethodInterceptor类型,这个同样是适配器完成的adapter.getInterceptor(advisor):

@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
		return new AfterReturningAdviceInterceptor(advice);
	}

我们知道不同的Advice执行顺序不同的,而且前面反复强调Advice最后都会转换为MethodInterceptor对象,然后最后通过这个对象调用相应的通知方法。比方说上面的AfterReturningAdviceInterceptor就是一个MethodInterceptor对象,我们看看它底层是如何封装Advice的。

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;

	public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}


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

}

关键是invoke函数,Object retVal = mi.proceed();这个就执行了代理目标的实际方法,advice.afterReturning(这个就是执行了代理逻辑。这就是MethodInterceptor最核心的逻辑。到此MethodInterceptor就封装完毕了。回到前面的invoke方法。我们获得Advisor链之后就会执行下面的逻辑:

if (chain.isEmpty()) {
		// 如果没有Advice,则直接调用对应方法
		Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
		retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}

上面代码的意思是如果我们没有加入任何Advisor,那么就会直接调用目标类的目标方法逻辑。否则就会执行下面的代码:

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

上面代码首先将MethodInterceptor数组封装为一个MethodInvocation对象,然后调用invocation.proceed,开始执行MethodInterceptor底层真正的逻辑。

@Override
	@Nullable
	public Object proceed() throws Throwable {

		// We start with an index of -1 and increment early.
		// currentInterceptorIndex初始值为-1,每调用一个interceptor就会加1
		// 当调用完了最后一个interceptor后就会执行被代理方法
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		// currentInterceptorIndex初始值为-1
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

		// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor
		// 如果没有匹配则递归调用proceed()方法,调用下一个interceptor
		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.
				// 不匹配则执行下一个MethodInterceptor
				return proceed();
			}
		}
		else {

			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			// 直接调用MethodInterceptor,传入this,在内部会再次调用proceed()方法进行递归
			// 比如MethodBeforeAdviceInterceptor
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

我们先看下面代码:

if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

this.currentInterceptorIndex ReflectiveMethodInvocation类的一个属性,默认值是-1,his.interceptorsAndDynamicMethodMatchers也是该类的一个属性,在构造ReflectiveMethodInvocation对象时会将我们前面照到的所有MethodInterceptor赋值给这个属性。这里我们先不说这个if判断的作用,先往后执行代码。

Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

上面代码就是取出下一个MethodInterceptor。然后继续看后面代码

// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor
		// 如果没有匹配则递归调用proceed()方法,调用下一个interceptor
		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.
				// 不匹配则执行下一个MethodInterceptor
				return proceed();
			}
		}
		else {

			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			// 直接调用MethodInterceptor,传入this,在内部会再次调用proceed()方法进行递归
			// 比如MethodBeforeAdviceInterceptor
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}

如果当前的MethodInterceptorInterceptorAndDynamicMethodMatcher类型,它需要进行参数匹配。如果不是该类型直接调用该MethodInterceptor的invoke方法。

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

然后Object retVal = mi.proceed();又调用了proceed方法,就开始执行下一个MethodInterceptor(有点套娃的意思),直到所有的MethodInterceptor执行完后,就回到第一个if判断了。

if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

现在进入invokeJoinpoint方法。

@Nullable
	protected Object invokeJoinpoint() throws Throwable {
		return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}
@Nullable
	public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
			throws Throwable {

		// Use reflection to invoke the method.
		try {
			ReflectionUtils.makeAccessible(method);
			// 执行普通对象的方法,注意和@Configuration产生的代理对象的逻辑区别
			return method.invoke(target, args);
		}
		catch (InvocationTargetException ex) {
			// Invoked method threw a checked exception.
			// We must rethrow it. The client won't see the interceptor.
			throw ex.getTargetException();
		}
		catch (IllegalArgumentException ex) {
			throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
					method + "] on target [" + target + "]", ex);
		}
		catch (IllegalAccessException ex) {
			throw new AopInvocationException("Could not access method [" + method + "]", ex);
		}
	}

关键就是这句代码return method.invoke(target, args)执行了被代理对象的指定方法。上面就是Spring AOP代理逻辑的执行过程。

3. ObjenesisCglibAopProxy

前面分析了JDK的动态代理,Cglib动态代理其实流程和这个差不多,我们简单的过一下。首先进入getProxy源码

@Override
	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;
			// 如果被代理类本身就已经是Cglib所生成的代理类了
			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.
			validateClassIfNecessary(proxySuperClass, classLoader);

			//定义增强器
			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));

			// 获取和被代理类所匹配的Advisor
			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);
		}
	}

和jdk动态代理不同,Cglib动态代理所有的Advisro都会放在一个Callback集合中。

Callback[] callbacks = getCallbacks(rootClass);

我们看看Cglib是怎么利用Advisor建立Callback数组的

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
		// 取ProxyFactory的属性
		boolean exposeProxy = this.advised.isExposeProxy();
		boolean isFrozen = this.advised.isFrozen();
		boolean isStatic = this.advised.getTargetSource().isStatic();

		// Choose an "aop" interceptor (used for AOP calls).
		Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
		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[] {
				aopInterceptor,  // for normal advice,执行Interceptor链
				targetInterceptor,  // invoke target without considering advice, if optimized 将代理对象设置到ThreadLocal中,AopContext.setCurrentProxy(proxy)
				new SerializableNoOp(),  // no override for methods mapped to this
				targetDispatcher, this.advisedDispatcher,
				new EqualsInterceptor(this.advised),
				new HashCodeInterceptor(this.advised)
		};

		Callback[] callbacks;
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = CollectionUtils.newHashMap(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;
	}

关键是这句代码Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);。这句代码就创建了一个DynamicAdvisedInterceptor对象,在使用cglib时这个callbacks数组里面存的对象其实就是MethodInterceptor,而这个类就是MethodInterceptor的子类。然后会调用intercept方法来执行代理逻辑。我们关键看这个intercept方法。

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Object target = null;
			TargetSource targetSource = this.advised.getTargetSource();
			try {
			//这个和jdk动态代理都在做一件事,观察当前的advisor的exposeProxy是否为true,如果是就设置到ThreadLocal中
				if (this.advised.exposeProxy) {
					// Make invocation available if necessary.
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				// 获取代理类
				target = targetSource.getTarget();
				//获取代理类类型
				Class<?> targetClass = (target != null ? target.getClass() : null);
				//和jdk一样这里同样是获得一个Advisor执行链
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
					retVal = methodProxy.invoke(target, argsToUse);
				}
				else {
					//然后执行proceed方法
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null && !targetSource.isStatic()) {
					targetSource.releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}

分析上面代码我们可以看出,它这里的逻辑其实和jdk动态代理的invoke逻辑是一样的。这里就不详细分析了。

经过前面的分析我们知道了ProxyFactory底层是如何利用jdk和Cglib生成代理对象,以及执行代理逻辑的。现在我们把视角放大,上面讲的东西和Spring AOP有什么关系呢?下面我们就开始分析Spring AOP源码。

三、 Spring AOP源码分析

首先经过前面的分析,我们知道AOP发生的过程是在bean的生命周期的初始化之后(这里不考虑循环依赖中提前AOP的情况)。所以我们进入doCreateBean方法。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
......
try {
			// 属性填充
			populateBean(beanName, mbd, instanceWrapper);

			// 初始化
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

......
}

exposedObject = initializeBean(beanName, exposedObject, mbd);这个就是执行Bean的初始化,我们进入initializeBean方法。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
		//执行回调方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;

		// 初始化前
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

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

		// 初始化后 AOP
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

注意上面代码就是一个Bean初始化后要做的事情,关于AOP这块就是在下面这段代码中:

// 初始化后 AOP
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
         //拿到当前的bean
		Object result = existingBean;
         //获取所有的BeanPostProcessor
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
		    //执行BeanPostProcessor的postProcessAfterInitialization
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

applyBeanPostProcessorsAfterInitialization方法的逻辑就是,找到所有的BeanPostProcessor然后执行每个BeanPostProcessor的postProcessAfterInitialization方法来执行初始化后的逻辑。这里我们先要知道AOP就是需要一个特定的BeanPostProcessor去执行它的postProcessAfterInitialization方法来实现AOP的。下面我们就来揭开这个特殊的BeanPostProcessor的面纱。

首先我们知道,要开启AOP我们需要在配置类上加入@EnableAspectJAutoProxy注解。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}
  • proxyTargetClass(): 默认值为 false,表示是否强制使用CGLIB代理方式。如果设置为 true,则表示使用CGLIB代理;否则使用JDK动态代理。
  • exposeProxy(): 默认值为 false,表示是否将当前代理对象暴露为ThreadLocal。如果设置为 true,则可以通过AopContext.currentProxy()来获取当前代理对象。

注意这个注解上面导入了@Import(AspectJAutoProxyRegistrar.class)在分析Spring启动源码的时候,我们分析过这个注解的作用可以起一个导入Bean的作用。这也是EnableAspectJAutoProxy注解的核心作用。我们就来分析一下这个类。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		// 注册一个AnnotationAwareAspectJAutoProxyCreator类型的Bean,beanName为AUTO_PROXY_CREATOR_BEAN_NAME
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		// 修改AnnotationAwareAspectJAutoProxyCreator中对应的属性
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

首先这个类实现了ImportBeanDefinitionRegistrar这个接口,所以这个类在Spring启动过程中会调用registerBeanDefinitions方法。方法里注册一个AnnotationAwareAspectJAutoProxyCreator类型的BeanDefinition,beanName为AUTO_PROXY_CREATOR_BEAN_NAME。这个Bean就是AOP的关键。

//1
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//2
@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
	}
//3
@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

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

//4 
@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;
		}
       //这里就是注册前面bean得逻辑
		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;
	}

下面我们就开始分析这个核心beanAUTO_PROXY_CREATOR_BEAN_NAME

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

	@Nullable
	private List<Pattern> includePatterns;

	@Nullable
	private AspectJAdvisorFactory aspectJAdvisorFactory;

	@Nullable
	private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;

	public void setIncludePatterns(List<String> patterns) {
		this.includePatterns = new ArrayList<>(patterns.size());
		for (String patternText : patterns) {
			this.includePatterns.add(Pattern.compile(patternText));
		}
	}

	public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
		Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
		this.aspectJAdvisorFactory = aspectJAdvisorFactory;
	}

	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.initBeanFactory(beanFactory);
		if (this.aspectJAdvisorFactory == null) {
			this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
		}
		this.aspectJAdvisorsBuilder =
				new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
	}


	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		// 先找到所有Advisor类型的Bean对象
		List<Advisor> advisors = super.findCandidateAdvisors();

		// Build Advisors for all AspectJ aspects in the bean factory.
		// 再从所有切面中解析得到Advisor对象
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

	@Override
	protected boolean isInfrastructureClass(Class<?> beanClass) {
		return (super.isInfrastructureClass(beanClass) ||
				(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
	}
	protected boolean isEligibleAspectBean(String beanName) {
		if (this.includePatterns == null) {
			return true;
		}
		else {
			for (Pattern pattern : this.includePatterns) {
				if (pattern.matcher(beanName).matches()) {
					return true;
				}
			}
			return false;
		}
	}
	private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {

		public BeanFactoryAspectJAdvisorsBuilderAdapter(
				ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {

			super(beanFactory, advisorFactory);
		}

		@Override
		protected boolean isEligibleBean(String beanName) {
			return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
		}
	}

}

我们从这个类开始不断找到它的父类,以及父类的父类,会来到这个类。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

}

它实现了implements SmartInstantiationAwareBeanPostProcessor说明,上面注册的那个bean确实是一个BeanPostProcessor。好现在我们知道了这个BeanPostProcessor,现在我们继续回到Bean的生命周期中。

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
         //拿到当前的bean
		Object result = existingBean;
         //获取所有的BeanPostProcessor
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
		    //执行BeanPostProcessor的postProcessAfterInitialization
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

关键代码就是执行bject current = processor.postProcessAfterInitialization(result, beanName);。然后上面关于AOP的BeanPostProcessor就会执行下面代码

@Override
	public Object postProcessAfterInstantiation(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

然后wrapIfNecessary就是创建真正的代理对象的逻辑

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}

		// this.advisedBeans表示已经判断过了的bean,false表示此bean不需要进行Aop  
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}

		// 当前正在创建的Bean不用进行AOP,比如切面Bean,advisedBeans里面就存储了不需要进行AOP的bean
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 判断当前bean是否存在匹配的advice,如果存在则要生成一个代理对象
		// 此处根据类以及类中的方法去匹配到Interceptor(也就是Advice),然后生成代理对象,代理对象在执行的时候,还会根据当前执行的方法去匹配
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			// advisedBeans记录了某个Bean已经进行过AOP了
			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的bean,如我们的加了Aspectj注解的bean,并加入到this.advisedBeans这个集合中。我们重点看下面代码:

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

其实上面的代码就是判断当前的bean需不需要进行AOP,相信大家还记得ProxyFactory的逻辑里面也进行了一次判断。如果要进行AOP,则进入的下面的if判断,否则这几返回bean。

if (specificInterceptors != DO_NOT_PROXY) {
			// advisedBeans记录了某个Bean已经进行过AOP了
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

上面调用了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);
		}
        //创建一个ProxyFactory
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (proxyFactory.isProxyTargetClass()) {
			// Explicit handling of JDK proxy targets (for introduction advice scenarios)
			if (Proxy.isProxyClass(beanClass)) {
				// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
				for (Class<?> ifc : beanClass.getInterfaces()) {
					proxyFactory.addInterface(ifc);
				}
			}
		}
		else {
			// No proxyTargetClass flag enforced, let's apply our default checks...
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		// 在这一步会去判断advisors中是否存在IntroductionAdvisor,如果存在则会把对应的interface添加到proxyFactory中去
		proxyFactory.addAdvisors(advisors);
		//设置Target
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

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

		// Use original ClassLoader if bean class not locally loaded in overriding class loader
		ClassLoader classLoader = getProxyClassLoader();
		if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
			classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
		}
		return proxyFactory.getProxy(classLoader);
	}

看到上面代码我们就会到了ProxyFactory的逻辑,这里就将SpringAOP和ProxyFactory联系起来了,后面如何产生代理对象,前面都分析了。proxyFactory.addAdvisors(advisors);就是添加Advisor,那么这个Advisor哪里来,其实就是参数中的 Object[] specificInterceptors这个数组,这个数组是由前面调用的getAdvicesAndAdvisorsForBean方法来的,假如现在BeanPostProcessor处理的bean为Userservice,通过该方法就可以找到所有和UserService有关的Advisor,我们看看这个方法底层是如何找的。

@Override
	@Nullable
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

		// 寻找匹配的Advisor
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

findEligibleAdvisors这个是寻找匹配的Advisor的核心方法,我们进入该方法。

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 找到所有的Advisor
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 进行筛选
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

		extendAdvisors(eligibleAdvisors);

		// 对Advisor进行排序,按Ordered接口、@Order注解进行排序
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

List<Advisor> candidateAdvisors = findCandidateAdvisors();就会找到所有的Advisor。

	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		// 先找到所有Advisor类型的Bean对象
		List<Advisor> advisors = super.findCandidateAdvisors();

		// Build Advisors for all AspectJ aspects in the bean factory.
		// 再从所有切面中解析得到Advisor对象
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

上面代码首先调用super.findCandidateAdvisors找到所有Advisor类型的bean,然后解析加了@AspectJ注解的bean解析出来。

public List<Advisor> buildAspectJAdvisors() {
		// aspectBeanNames是用来缓存BeanFactory中所存在的切面beanName的,第一次为null,后面就不为null了,不为null表示之前就已经找到过BeanFactory中的切面了
		List<String> aspectNames = this.aspectBeanNames;

		if (aspectNames == null) {
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new ArrayList<>();
					aspectNames = new ArrayList<>();

					// 把所有beanNames拿出来遍历,判断某个bean的类型是否是Aspect
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					for (String beanName : beanNames) {
						if (!isEligibleBean(beanName)) {
							continue;
						}
						//获取当前bean的类型
						Class<?> beanType = this.beanFactory.getType(beanName, false);
						if (beanType == null) {
							continue;
						}
						//判断当前类型bean上面是否有AspectJ注解
						if (this.advisorFactory.isAspect(beanType)) {
							aspectNames.add(beanName);
							// 切面的注解信息
							AspectMetadata amd = new AspectMetadata(beanType, beanName);

							// 如果@Aspect不是perthis、pertarget,那么一个切面只会生成一个对象(单例)
							// 并且会将该切面中所对应的Advisor对象进行缓存
							if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								// 利用BeanFactoryAspectInstanceFactory来解析Aspect类
								List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
								if (this.beanFactory.isSingleton(beanName)) {
									// 缓存切面所对应的所有Advisor对象
									this.advisorsCache.put(beanName, classAdvisors);
								}
								else {
									this.aspectFactoryCache.put(beanName, factory);
								}
								advisors.addAll(classAdvisors);
							}
							else {
								// Per target or per this.
								if (this.beanFactory.isSingleton(beanName)) {
									throw new IllegalArgumentException("Bean with name '" + beanName +
											"' is a singleton, but aspect instantiation model is not singleton");
								}
								MetadataAwareAspectInstanceFactory factory =
										new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
								this.aspectFactoryCache.put(beanName, factory);
								// 利用PrototypeAspectInstanceFactory来解析Aspect类
								// PrototypeAspectInstanceFactory的父类为BeanFactoryAspectInstanceFactory
								// 这两个Factory的区别在于PrototypeAspectInstanceFactory的构造方法中会判断切面Bean是不是原型,除此之外没有其他区别
								// 所以主要就是BeanFactoryAspectInstanceFactory来负责生成切面实例对象
								advisors.addAll(this.advisorFactory.getAdvisors(factory));
							}
						}
					}
					this.aspectBeanNames = aspectNames;
					return advisors;
				}
			}
		}

		if (aspectNames.isEmpty()) {
			return Collections.emptyList();
		}

		// 如果切面已经找到过了,那么则遍历每个切面是否缓存了对应的Advisor,如果没有缓存则进行解析得到Advisor
		List<Advisor> advisors = new ArrayList<>();
		for (String aspectName : aspectNames) {
			List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
			if (cachedAdvisors != null) {
				advisors.addAll(cachedAdvisors);
			}
			else {
				MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
				advisors.addAll(this.advisorFactory.getAdvisors(factory));
			}
		}
		return advisors;
	}

上面的类就是解析加了@Aspectj注解的bean,其实就是解析里面的@Before等注解,然后生成一系列的Advisor对象返回,底层还是很复杂的,这里就不深入分析了。回到wrapIfNecessary,现在就找到了很多Advisor。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/316613.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL注入攻击

1.用java实现登录的检查 package jdbc1;import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner;public class Login {public static void main(String args[]){try(Connection connec…

新型的变现和引流方式

AI 数字人短视频正成为一种新型的变现和引流方式。随着人工智能技术的不断发展&#xff0c;数字人技术也越来越成熟&#xff0c;为用户提供了更加逼真、生动的虚拟形象。通过AI 数字人短视频&#xff0c;用户可以创作出具有个性化特点的短视频内容&#xff0c;并将其发布在各大…

PLC控制脉冲轴绝对位置往复运动(三菱FX系列简单状态机编程)

有关状态机的具体介绍,专栏有很多文章,大家可以通过下面的链接查看: https://rxxw-control.blog.csdn.net/article/details/125488089https://rxxw-control.blog.csdn.net/article/details/125488089三菱FX系列回原功能块介绍 https://rxxw-control.blog.csdn.net/article…

在vue3和上挂载方法,以及在页面中怎么使用原型(公共)上的方法

//新建的项目的main.js文件是这样的 //main.js 文件 //befor import { createApp } from vue; import App from ./App.vue;const app createApp(App); app.mount(#app);以下例子用于解释在vue3.0的main.js中挂载公共的方法&#xff08;foo&#xff09; //main.js 文件 //afte…

51-11 多模态论文串讲—VLMo 论文精读

VLMo: Unified Vision-Language Pre-Training with Mixture-of-Modality-Experts (NeurIPS 2022) VLMo 是一种多模态 Transformer 模型&#xff0c;从名字可以看得出来它是一种 Mixture-of-Modality-Experts (MoME)&#xff0c;即混合多模态专家。怎么理解呢&#xff1f;主流 …

解决ELK日志收集中Logstash报错的关键步

ElK执行日志收集的时候logstash报错&#xff1a; Failed to execute action {:action>LogStash::PipelineAction::Create/pipeline_id:main, :exception>“LogStash::ConfigurationError”, :message>“Expected one of [^\r\n], “\r”, “\n” at line 88, column 4…

【深度学习每日小知识】Overfitting 过拟合

过拟合是机器学习&#xff08;ML&#xff09;中的常见问题&#xff0c;是指模型过于复杂&#xff0c;泛化能力较差的场景。当模型在有限数量的数据上进行训练&#xff0c;并且学习了特定于该特定数据集的模式&#xff0c;而不是适用于新的、看不见的数据的一般模式时&#xff0…

不用下载就可以使用的三个在线抠图网站

字图像处理技术的发展&#xff0c;抠图已经成为一项重要的技术。在许多情况下&#xff0c;我们需要将图片中的某一部分抠出来&#xff0c;例如将人物从背景中抠出&#xff0c;或者将产品从图片中抠出。传统的抠图方法需要使用专业的图像处理软件&#xff0c;如Photoshop等&…

22k+stars centos轻松搭建网盘的神器

说明: 系统:centos7 64 ip:192.168.168.107 目录 1.下载 2.安装 3.启动 4.测试 1.下载 根据系统下载 wget https://github.com/filebrowser/filebrowser/releases/download/v2.27.0/linux-amd64-filebrowser.tar.gz 2.安装 tar -zxvf linux-amd64-filebrowser.tar.gz…

Linux限制用户可用硬盘空间

为了防止某个用户占用大量资源导致其他用户无法正常使用&#xff0c;一般会对单个用户可占用资源进行限制。就磁盘限额&#xff0c;XFS文件系统原生支持目录级别的限制。ext文件系统不支持目录限制&#xff0c;曲线方式是限制用户的总占用空间。 本文介绍使用quota程序限制用户…

有没有可以拖拉拽生成一个低代码平台?

据我所知&#xff0c;低代码平台都能拖拉拽生成。作为一组数字技术工具平台&#xff0c;它能基于图形化拖拽、参数化配置等更为高效的方式&#xff0c;实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。 到底啥是低代码&…

网络——华为与华三

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆云计算学堂 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ 写在前面 大家好&#xff0c;我是网络豆&#xff0…

10-skywalking告警

https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/backend-alarm.md 5.1&#xff1a;告警指标 ~$ vim /apps/apache-skywalking-apm-bin/config/oal/core.oal service_resp_time # 服务的响应时间 service_sla # 服务http请求成功率SLV&#xff0c;比…

渗透测试:保障网络安全的重要手段!

随着信息技术的快速发展&#xff0c;网络安全问题日益受到关注。渗透测试作为一种重要的网络安全检测和评估方法&#xff0c;已经成为保障网络安全的重要手段之一。本文将介绍渗透测试的基本概念、流程、以及在保障网络安全方面的应用。 一、渗透测试的基本概念 渗透测试是一…

机器学习第二十五周周报 ConvLSTM

文章目录 week 25 ConvLSTM摘要Abstract一、李宏毅机器学习二、文献阅读1. 题目2. abstract3. 网络架构3.1降水预报问题的建模3.2Convolutional LSTM3.3编码-预测结构 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1Moving-MNIST Dataset4.3.2雷达回波数据集 4.4 结论…

你真的读懂了“in”运算符吗?

in运算符用户判断属性是否存在于对象中。 语法 key in obj;参数 示例 var cars new Array(Toyota, Nissan, Mercedes, Buick, Porsche); 0 in cars; // true1 in cars; // true6 in cars; // falseMercedes in cars; // false&#xff08;必须使用索引号&#xff0c;而不是…

点的旋转变换

情形一&#xff08;active or alibi transformation主动变换&#xff09; 在坐标系 x − y x-y x−y中&#xff0c;点 p 1 p_1 p1​逆时针旋转 α \alpha α后到达点 p 2 p_2 p2​。 p 1 p_1 p1​在 x − y x-y x−y中的表示与 p 2 p_2 p2​在 x ′ − y ′ x-y x′−y′中的表…

如何异地链接Pycharm服务器进行远程开发并实现与公司服务器资源同步

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

Webm文件转MP4

WebM由Google提出&#xff0c;是一个开放、免费的媒体文件格式。WebM 影片格式其实是以 Matroska&#xff08;即 MKV&#xff09;容器格式为基础开发的新容器格式&#xff0c;里面包括了VP8影片轨和 Ogg Vorbis 音轨&#xff0c;其中Google将其拥有的VP8视频编码技术以类似BSD授…

Unity中URP下实现深度贴花(雾效支持和BRP适配)

文章目录 前言一、让我们的贴画支持雾效1、我们舍弃内部的MixFog方法2、使用 雾效混合因子 对最后输出颜色进行线性插值相乘 二、在Shader中&#xff0c;限制贴花纹理的采样方式1、申明 纹理 和 限制采样方式的采样器2、在片元着色器进行纹理采样 三、BRP适配1、C#脚本中&#…