Spring AOP源码剖析:代理对象创建流程

Posted 丿涛哥哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP源码剖析:代理对象创建流程相关的知识,希望对你有一定的参考价值。

Spring AOP源码剖析:代理对象创建流程

代理对象创建

1、 AOP基础用例准备

Bean定义

@Component
public class LagouBean {
	public void tech(){
	System.out.println("java learning......");
	}
}

Aspect定义

@Component
@Aspect
public class LagouAspect {
	@Pointcut("execution(* com.tao.*.*(..))")
	public void pointcut(){
	}
    
	@Before("pointcut()")
	public void before() {
		System.out.println("before method ......");
	}
}

测试用例

/**
* 测试用例:Aop 代理对象创建
*/
@Test
public void testAopProxyBuild(){
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
    LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
    lagouBean.tech();
}

2、 时机点分析

Spring_51

我们发现在 getBean 之前,LagouBean对象已经产生(即在第一行初始化代码中完成),而且该对象是一个代理对象(Cglib代理对象),我们断定,容器初始化过程中⽬标Ban已经完成了代理,返回了代理对象。

3、 代理对象创建流程

AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

/**
 *
 * 初始化Bean
 包括Bean后置处理器初始化
 Bean的一些初始化⽅法的执行init-method
 Bean的实现的声明周期相关接⼝的属性注⼊
 */
protected Object initializeBean(final String beanName, final Object bean,
								@Nullable RootBeanDefinition mbd) {
	// 执行所有的AwareMethods
	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()) {
		// 执行所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器⽅法
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);
	}
	try {
		// 这里就开始执行afterPropertiesSet(实现了InitializingBean接⼝)⽅法和 initMethod
		invokeInitMethods(beanName, wrappedBean, mbd);
	} catch (Throwable ex) {
		throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
						beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
		// 整个Bean初始化完成,执行后置处理器⽅法
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean,beanName);
	}
	return wrappedBean;
}

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
				throws BeansException {
	Object result = existingBean;
	// 循环执行后置处理器
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result,beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

在这里插入图片描述

创建代理对象的后置处理器AbstractAutoProxyCreator#postProcessAfterInitialization

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		// 检查下该类是否已经暴露过了(可能已经创建了,⽐如A依赖B时,创建A时候,就会先去创建B。
		// 当真正需要创建B时,就没必要再代理一次已经代理过的对象),避免重复创建
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

AbstractAutoProxyCreator#wrapIfNecessary

/**
 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
 * @param bean the raw bean instance
 * @param beanName the name of the bean
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	// targetSourcedBeans包含,说明前⾯创建过
	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.
	// 得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到一个
	List<Advisor>,即specificInterceptors
	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;
}

AbstractAutoProxyCreator#createProxy

/**
 * Create an AOP proxy for the given bean.
 * 为指定 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 proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);
	// 根据一些情况判断是否要设置proxyTargetClass=true
	if (!proxyFactory.isProxyTargetClass()) {
		if (shouldProxyTargetClass(beanClass, beanName)) {
			proxyFactory.setProxyTargetClass(true);
		}else {
			evaluateProxyInterfaces(beanClass, proxyFactory);
		}
	}
	// 把指定和通用拦截对象合并, 并都适配成Advisor
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	proxyFactory.addAdvisors(advisors);
	// 设置参数
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);
	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	// 上⾯准备做完就开始创建代理
	return proxyFactory.getProxy(getProxyClassLoader());
}

接着跟进到ProxyFactory中

public class ProxyFactory extends ProxyCreatorSupport {
    public Object getProxy(ClassLoader classLoader) {
        // 用ProxyFactory创建AopProxy, 然后用AopProxy创建Proxy, 所以这里重要的是看获取的AopProxy
        // 对象是什么,
        // 然后进去看怎么创建动态代理, 提供了两种:jdk proxy, cglib
        return createAopProxy().getProxy(classLoader);
    }
}


public class ProxyCreatorSupport extends AdvisedSupport {
	private AopProxyFactory aopProxyFactory;

	public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
    
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		//先获取创建AopProxy的工厂, 再由此创建AopProxy
		return getAopProxyFactory().createAopProxy(this);
	}
    
	public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}
}

流程就是用AopProxyFactory创建AopProxy, 再用AopProxy创建代理对象,这里的AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy方法

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
    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 targetclass: " + 
                                             "Either an interface or a target is required for proxy creation.");
            }
            if (targetClass.isInterface()) {
                return new JdkDynamicAopProxy(config);
            }
                return new ObjenesisCglibAopProxy(config);
        } else {
            return new JdkDynamicAopProxy(config);
        }
    }

    /**
    * Determine whether the supplied {@link AdvisedSupport} has only the
    * {@link org.springframework.aop.SpringProxy} interface specified (or no
    * proxy interfaces specified at all).
    */
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class<?>[] interfaces = config.getProxiedInterfaces();
        return (interfaces.length == 0 || (interfaces.length == 1 &&
                SpringProxy.class.equals(interfaces[0])));
    }
}

这里决定创建代理对象是用JDK Proxy,还是用 Cglib 了,最简单的从使用方⾯使用来说:设置 proxyTargetClass=true强制使用Cglib 代理,什么参数都不设并且对象类实现了接口则默认用JDK代理,如果没有实现接口则也必须用Cglib

ProxyFactory#getProxy(java.lang.ClassLoader) ------ CglibAopProxy#getProxy(java.lang.ClassLoader)

@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;
		if (ClassUtils.isCglibProxyClass(rootClass)) {
			proxySuperClass = rootClass.getSuperclass();
			Class<?>[] additionalInterfaces = rootClass.getInterfaces();
			for (Class<?> additionalInterface : additionalInterfaces) {
				this.advised.addInterface(additionalInterface);
			}
		}
		// Validate the class, writing log messages as necessary.
		validateClassIfNecessary(proxySuperClass, classLoader);
		// 配置 Cglib 增强
		Enhancer enhancer = createEnhancer();
		if (classLoader != null) {
			enhancer.setClassLoader(classLoader);
			if (classLoader instanceof SmartClassLoader && 
                	((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
				enhancer.setUseCache(false);
			}

        enhancer.setSuperclass(proxySuperClass);
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
		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);
		// 生成代理类,并且创建一个代理类的实例
		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 anon-visible class",ex);
	} catch (Throwable ex) {
		// TargetSource.getTarget() failed
		throw new AopConfigException("Unexpected AOP exception", ex);
	}
}

AOP源码分析类方法调用关系记录:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean

调用

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)

调用

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

调用

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy (在这一步把委托对象的aop增强和通用拦截进行合并,最终给代理对象)

调用

org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy

调用

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

以上是关于Spring AOP源码剖析:代理对象创建流程的主要内容,如果未能解决你的问题,请参考以下文章

Spring AOP源码剖析

Spring AOP源码剖析

61 张图,剖析 Spring 事务,就是要钻到底!

深入浅出Spring原理及实战「原理分析专题」不看源码就带你剖析AOP容器核心流程以及运作原理

Spring读源码系列之AOP--08--aop执行完整源码流程之自动代理创建器导入的两种方式

Spring框架进阶Spring V3.0 AOP源码分析流程