深入理解Spring AOP代理对象创建过程

645 阅读4分钟

1 InfrastructureAdvisorAutoProxyCreator

在spring boot中使用此类来进行AOP的。它是一个BeanPostProcessor,所以实在Bean的生命周期中BeanPostProcessor处理的。因为AOP在Spring中实际上就是对原来的targetClass对象进行包装,所以需要先有一个TargetClass,然后才能进行包装。同样对于Bean需要将Bean首先进行实例化并给属性赋值后才能进行AOP包装,也就自然使用BeanPostProcessor来进行处理。

2 postProcessAfterInitialization

BeanPostProcessor 的标准入口

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
	    // 从cache中获取
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		// 如果获取到的不等于(包括为null)传进来的Bean则进行接下来的处理,
		// 判断是否需要AOP,
		// 不需要就直接缓存这个Bean并返回;
		// 如果需要则首先进行AOP处理,然后再缓存AOP后的对象后返回
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

3 wrapIfNecessary

获取拦截器(advisor) ---> AOP代理

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

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

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

4 getAdvicesAndAdvisorsForBean

调用findEligibleAdvisors找到可以用用到当前类的Advisor

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

	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

5 findEligibleAdvisors

findCandidateAdvisors()找到所有的在IoC容器中的Advisor,实际上使用的方法就是遍历所有的Bean如果是Advisor的子类就返回

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 从IoC容器中找到所有的Advisor
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	// 找到符合当前对象的Advisor
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

6 findAdvisorsThatCanApply

使用AopUtils工具找到符合当前对象的Advisor

protected List<Advisor> findAdvisorsThatCanApply(
		List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

	ProxyCreationContext.setCurrentProxiedBeanName(beanName);
	try {
	    // 使用AopUtils工具
		return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
	}
	finally {
		ProxyCreationContext.setCurrentProxiedBeanName(null);
	}
}

7 AopUtils#findAdvisorsThatCanApply

调用canApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	if (candidateAdvisors.isEmpty()) {
		return candidateAdvisors;
	}
	List<Advisor> eligibleAdvisors = new ArrayList<>();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
			eligibleAdvisors.add(candidate);
		}
	}
	boolean hasIntroductions = !eligibleAdvisors.isEmpty();
	for (Advisor candidate : candidateAdvisors) {
		if (candidate instanceof IntroductionAdvisor) {
			// already processed
			continue;
		}
		// 调用
		if (canApply(candidate, clazz, hasIntroductions)) {
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}

8 AopUtils#canApply

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
	if (advisor instanceof IntroductionAdvisor) {
		return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
	}
	else if (advisor instanceof PointcutAdvisor) {
		PointcutAdvisor pca = (PointcutAdvisor) advisor;
		return canApply(pca.getPointcut(), targetClass, hasIntroductions);
	}
	else {
		// It doesn't have a pointcut so we assume it applies.
		return true;
	}
}

9 AopUtils#canApply

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
	Assert.notNull(pc, "Pointcut must not be null");
	if (!pc.getClassFilter().matches(targetClass)) {
		return false;
	}

    // 标准的AOP组件
	MethodMatcher methodMatcher = pc.getMethodMatcher();
	if (methodMatcher == MethodMatcher.TRUE) {
		// No need to iterate the methods if we're matching any method anyway...
		return true;
	}

	IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
	if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
		introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
	}

	Set<Class<?>> classes = new LinkedHashSet<>();
	if (!Proxy.isProxyClass(targetClass)) {
		classes.add(ClassUtils.getUserClass(targetClass));
	}
	classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

	for (Class<?> clazz : classes) {
	    // 使用反射获得对象的所有声明的方法
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); 
		// 遍历目标对象的所有声明的methods
		for (Method method : methods) {
			if (introductionAwareMethodMatcher != null ?
					introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
					methodMatcher.matches(method, targetClass)) {
				return true;
			}
		}
	}

	return false;
}

10 methodMatcher.matches(method, targetClass)

调用这个方法看当前的对象是否符合当前的这个pointCu t

每个methodMather的matches实现方式是不一样的

后面会用Spring Cache为例子进行讲解

11 InfrastructureAdvisorAutoProxyCreator#createProxy

通过上面的一系列方法找到了匹配的Advisor后,接下来就是使用Advisor来创建AOP代理对象了

Object proxy = createProxy(
		bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
		@Nullable Object[] specificInterceptors, TargetSource targetSource) {

	if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
		AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
	}
    
    // 创建代理工厂
	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);

	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}
		else {
		    // 评估是否实现了接口
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}

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

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

    // 调用工厂的getProxy来获取代理对象
    // 使用了工厂模式,将需要的原材料给工厂,工厂就会为你创建代理对象返回
	return proxyFactory.getProxy(getProxyClassLoader());
}

12 proxyFactory#getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    将代理对象用AopProxy进行包装
	return createAopProxy().getProxy(classLoader);
}

13 proxyFactory#createAopProxy()

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

14 getAopProxyFactory()

获取的是DefaultAopProxyFactory()

public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}

15 DefaultAopProxyFactory#createAopProxy

判断使用Cglib进行创建,还是使用JDK进行创建,这里以JDK创建为例

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
		Class<?> targetClass = config.getTargetClass();
		if (targetClass == null) {
			throw new AopConfigException("TargetSource cannot determine target class: " +
					"Either an interface or a target is required for proxy creation.");
		}
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

16 new JdkDynamicAopProxy(config)

返回一个JDKDynamicAopProxy代理对象就可以了。

17 dkDynamicAopProxy#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);
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
	// jdk动态创建代理对象的标准做法,可以看到this就是invokationHandler
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}