Spring AOP(四)【源码分析】基于注解的AOP——第3步:根据Advisor创建代理


本系列主要分析基于注解形式的SpringAOP实现流程,大致可以分为以下几个核心步骤:

  • 解析配置aspectj-autoproxy
  • 加载Aspect切面和Advisor
  • 创建代理
  • 调用代理对象中的方法

Bean创建过程中的postProcessBeforeInstantiation:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		if (beanName != null) {
			TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
			if (targetSource != null) {
				this.targetSourcedBeans.add(beanName);
				Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
				Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
				this.proxyTypes.put(cacheKey, proxy.getClass());
				return proxy;
			}
		}

		return null;
	}

上文我们分析到getAdvicesAndAdvisorsForBean方法,得到了一个适用于当前Bean的Advisor集合;
接下来继续createProxy方法,即创建代理。

第三步:创建代理

Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
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();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

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

		return proxyFactory.getProxy(getProxyClassLoader());
	}

此方法的关键步骤:

  1. 创建代理工厂ProxyFactory
  2. 将interceptor统一适配为Advisor
  3. proxyFactory.getProxy获取代理

1.buildAdvisors统一适配为Advisor

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
		// Handle prototypes correctly...
		Advisor[] commonInterceptors = resolveInterceptorNames();

		List<Object> allInterceptors = new ArrayList<Object>();
		if (specificInterceptors != null) {
			allInterceptors.addAll(Arrays.asList(specificInterceptors));
			if (commonInterceptors.length > 0) {
				if (this.applyCommonInterceptorsFirst) {
					allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
				}
				else {
					allInterceptors.addAll(Arrays.asList(commonInterceptors));
				}
			}
		}
		if (logger.isDebugEnabled()) {
			int nrOfCommonInterceptors = commonInterceptors.length;
			int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
			logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
					" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
		}

		Advisor[] advisors = new Advisor[allInterceptors.size()];
		for (int i = 0; i < allInterceptors.size(); i++) {
			advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
		}
		return advisors;
	}

适配方法为advisorAdapterRegistry.wrap:

public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
		if (adviceObject instanceof Advisor) {
			return (Advisor) adviceObject;
		}
		if (!(adviceObject instanceof Advice)) {
			throw new UnknownAdviceTypeException(adviceObject);
		}
		Advice advice = (Advice) adviceObject;
		if (advice instanceof MethodInterceptor) {
			// So well-known it doesn't even need an adapter.
			return new DefaultPointcutAdvisor(advice);
		}
		for (AdvisorAdapter adapter : this.adapters) {
			// Check that it is supported.
			if (adapter.supportsAdvice(advice)) {
				return new DefaultPointcutAdvisor(advice);
			}
		}
		throw new UnknownAdviceTypeException(advice);
	}

方法中的this.adapters在初始化时注册进去的适配器有:

public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}

而这三种适配器所支持的Advice类型分别为:

// MethodBeforeAdviceAdapter
public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
}
//AfterReturningAdviceAdapter
public boolean supportsAdvice(Advice advice) {
		return (advice instanceof AfterReturningAdvice);
}
//ThrowsAdviceAdapter
public boolean supportsAdvice(Advice advice) {
		return (advice instanceof ThrowsAdvice);
}

再来分析wrap方法,将传来的增强器分为了三种:

  • Advisor类型,直接返回Advisor;
  • Advice类型,包装为DefaultPointcutAdvisor返回;
    1. MethodInterceptor类型
    2. MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice类型

Spring AOP(二)AOPAlliance与SpringAOP核心接口介绍中,我们可以找到这几种名词之间的关系:除了Advisor之外,还有可能是我们直接实现了Advice系列的接口(在Spring的低版本中支持此种方式)。
在这里插入图片描述

Spring AOP 使用介绍,从前世到今生
中描述了实现Advice接口的方式;

本节中分析的是基于@Aspect注解的形式,故传入的增强器都是上篇中所述创建的Advisor,直接返回。

2.proxyFactory.getProxy获取代理

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

2.1. createAopProxy决定使用Jdk或CgLib方式创建代理

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		//config.isOptimize() :是否需要优化,是专门针对于CGlib代理的优化策略,并不推荐属于此配置;
		//config.isProxyTargetClass() :检测 proxyTargetClass 的值
		//hasNoUserSuppliedProxyInterfaces(config) :是否存在代理接口
		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);
		}
	}

决定策略总结来说就是:

  • 如果目标对象实现了接口,则优先使用 JDK 代理
  • 如果目标对象实现了接口,可以设置proxy-target-class属性为true,强制使用CgLib代理
  • 如果目标对象没有实现接口,则必须使用 CGLIB 进行代理

2.2. getProxy创建代理

下篇详细分析两种代理创建的流程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值