【十三】Spring源码分析之AOP----AbstractAutoProxyCreator生成代理对象

一、简介

AOP源码分析主要分为5个篇章:前面3篇已经讲了

1. 注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator

【十】Spring源码分析之AOP----注册、实例化、初始化AnnotationAwareAspectJAutoProxyCreator
2. 扫描容器中的切面,创建PointcutAdvisor对象
【十一】Spring源码分析之AOP----AnnotationAwareAspectJAutoProxyCreator扫描@Aspect,创建Advisor

3.解析pointcut切点的表达式,看该目标bean与哪些Advisor匹配

【十二】Spring源码分析之AOP----匹配出作用于被代理类Advisor

4.Spring源码分析之AOP----生成代理对象。就是本篇。

5. 被代理类的方法一次调用流程。

【十四】Spring源码分析之AOP----JdkDynamicAopProxy代理对象invoke调用

本篇讲述:

AOP创建代理实例,包括cglib和JDK 

方法调用栈:

入口:

AbstractAutoProxyCreator类的createProxy方法

源码:

protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            // 暴露目标类
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

        // 新建代理工厂
		ProxyFactory proxyFactory = new ProxyFactory();

        // 当前ProxyCreator在创建代理时将需要用到的字段赋值到ProxyFactory中去
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {

            //是否使用targetClass类,而不是接口来进行代理
			if (shouldProxyTargetClass(beanClass, beanName)) {

                // 使用目标类来代理,这基本上就是会用cglib代理了
				proxyFactory.setProxyTargetClass(true);
			}
			else {

                // 使用接口代理,会调用这个方法看到底使用哪个接口,如果找不到合适的接口还是会用目标类本身来代理
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

        // 将该bean的所有Advisor以及拦截器统一封装成Advisor,并设置到proxyFactory中
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

        // 往代理工厂中加入Advisor
		proxyFactory.addAdvisors(advisors);

        // 往代理工厂中加入目标类
		proxyFactory.setTargetSource(targetSource);

        // 定制代理工厂
		customizeProxyFactory(proxyFactory);

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

        // 从代理工厂中获取代理实例
		return proxyFactory.getProxy(getProxyClassLoader());
	}

做了7件事:

1.如果beanFactory是ConfigurableListableBeanFactory的类型,暴露目标类。

2.创建一个ProxyFactory,当前ProxyCreator在创建代理时将需要用到的字段赋值到ProxyFactory中去。

3.判断是否使用targetClass目标类本身来代理

4.将该bean的所有Advisor以及拦截器统一封装成Advisor,并设置到proxyFactory中。

5.往代理工厂中加入目标类

6.定制代理工厂

7.从代理工厂中获取代理实例

二、proxyFactory.getProxy方法

源码:

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

做了2件事:

1.创建AOP代理

2.获取代理实例

三、createAopProxy方法

 源码:

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

追踪进getAopProxyFactory方法发现返回的就是一个DefaultAopProxyFactory类

调用DefaultAopProxyFactory类的createAopProxy方法

源码:

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

做了1件事:基于接口的代理就new JdkDynamicAopProxy,没有接口的代理就new ObjenesisCglibAopProxy

这里我的目标类不是基于接口的,所以是new ObjenesisCglibAopProxy走得cglib代理。

四、 CglibAopProxy类的getProxy方法

由于这里是cglib代理,调用的是CglibAopProxy类的getProxy方法

源码:

public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
		}

		try {

            //从advised 中获取目标对象
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

			Class<?> proxySuperClass = rootClass;

            // 这里判断rootClass是否是Cglib代理所产生的类(内部判断rootClass的className是否包含$$)
			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.

            // 验证proxySuperClass中的是否有final方法(有则打印出来警告信息,该方法不能被代理)  
			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 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

            // 设置回调过滤ClassFilter和回调类型
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));

            // 设置一组callback的type
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
            // 生成代理类,创建代理实例
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		catch (CodeGenerationException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of class [" +
					this.advised.getTargetClass() + "]: " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (IllegalArgumentException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of class [" +
					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);
		}
	}

做了4件事:

1.从advised 中获取目标对象,判断rootClass是否是Cglib代理所产生的类(内部判断rootClass的className是否包含$$),如果是就取目标类的父类作为目标类

2.验证proxySuperClass中的是否有final方法(有则打印出来警告信息,该方法不能被代理)  

3.创建配置Enhancer

4.获取callbacks回调方法有6个(DynamicAdvisedInterceptor、StaticUnadvisedInterceptor(我debug的时候这里是用的这个,不是用的StaticUnadvisedExposedInterceptor)、SerializableNoOp、StaticDispatcher、EqualsInterceptor、HashCodeInterceptor)

5.为Enhancer设置回调过滤callbackFilter(用的ProxyCallbackFilter)和回调类型

6.createProxyClassAndInstance生成代理类,创建代理实例。这里面会用到前面设置进来的callbackFilter。之后专门写一篇文章介绍这个方法。

4.1 getCallbacks 获取回调方法

源码:

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
		// Parameters used for optimization choices...
		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 这个DynamicAdvisedInterceptor是一个实现了MethodInterceptor接口的类
		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 {

            // 创建一个callback,是一个实现了MethodInterceptor接口的类
			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,是一个实现了MethodInterceptor接口的类
		Callback targetDispatcher = isStatic ?
				new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();

        // 把7个callback,即是MethodInterceptor放到callback组中
		Callback[] mainCallbacks = new 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.

        // 如果目标是static,并且advicechain是fronze时
        // debug的时候没有找到这里面去,暂时不知道这个到底是干嘛的
		if (isStatic && isFrozen) {
			Method[] methods = rootClass.getMethods();
			Callback[] fixedCallbacks = new Callback[methods.length];
			this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);

			// TODO: small memory optimization here (can skip creation for methods with no advice)
			for (int x = 0; x < methods.length; x++) {
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
				fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
						chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
				this.fixedInterceptorMap.put(methods[x].toString(), 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;
	}

做了1件事:

创建一组cgblic的callbacks,在里面加入了7个MethodInterceptor:

1.DynamicAdvisedInterceptor

2.StaticUnadvisedInterceptor(我debug的时候这里是用的这个,不是用的StaticUnadvisedExposedInterceptor)

3.SerializableNoOp

4.StaticDispatcher

5.AdvisedDispatcher

6.EqualsInterceptor

7.HashCodeInterceptor

五、JdkDynamicAopProxy类的getProxy方法

测试一个有接口的被代理目标类,看一下JdkDynamicAopProxy类的getProxy方法

源码:

public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}

        // 得到代理接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

做了3件事:

1.得到代理接口,这里除了我写的目标类本来实现的接口以外,还有3个(interface org.springframework.aop.SpringProxy、interface org.springframework.aop.framework.Advised、interface org.springframework.core.DecoratingProxy

2.设置JdkDynamicAopProxy类的equalsDefined和hashCodeDefined属性。

3.生成代理对象。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值