Spring源码解读(九)创建AOP代理——根据增强器创建代理

前言

创建AOP代理的逻辑,主要分为两个部分讲解,一是获取增强器或者增强方法,二是对增强器或者增强方法进行代理。上篇博文分析了解获取增强器或者增强方法的流程,接下来继续分析根据获取到的增强器创建代理的流程。

程序入口

从AbstractAutoProxyCreator#wrapIfNecessary方法进入,调用AbstractAutoProxyCreator#createProxy开始创建代理。

	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)) {
			// 如果事一个基础设置类
			// 或者配置了指定的bean不需要代理
			// 即设置为不需要代理,然后返回
			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;
	}

初始化ProxyFactory

AbstractAutoProxyCreator#createProxy的功能是对proxyFactory进行实例化和初始化的操作,然后委托 ProxyFactory 去创建代理。

初始化操作主要包括:

  • 提前暴露ConfigurationListableBeanFactory
  • 获取当前类的属性
  • 如果是引介增强场景要显示处理JDK代理目标
  • 构建Advisors
  • 子类对ProxyFactory进一步封装
  • 获取代理对象
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
		// 如果是ConfigurableListableBeanFactory,设置提前暴露
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}
		// 创建代理工厂
		ProxyFactory proxyFactory = new ProxyFactory();
		// 复制当前类中的相关属性到代理工厂
		proxyFactory.copyFrom(this);

		// 判断是否代理目标类
		if (proxyFactory.isProxyTargetClass()) {
			// Explicit handling of JDK proxy targets (for introduction advice scenarios)
			// 显式处理 JDK 代理目标(用于引介增强场景)
			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 {
			// 确定给定的 bean 是否应该使用它的目标类而不是它的接口来代理
			// 主要判断PRESERVE_TARGET_CLASS_ATTRIBUTE属性 preserveTargetClass
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		// 构建增强器
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		// 加入增强器
		proxyFactory.addAdvisors(advisors);
		// 设置要代理目标类
		proxyFactory.setTargetSource(targetSource);
		// 定制代理工厂
		customizeProxyFactory(proxyFactory);
		// 控制代理工厂被配置后 是否允许修改通知。
		// 默认false
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		// 初始化工作准备完毕,委托ProxyFactory处理具体逻辑
		return proxyFactory.getProxy(getProxyClassLoader());
	}

这个方法内构建Advisors加入ProxyFactory和创建代理两个流程比较繁琐。

构建Advisors

AbstractAutoProxyCreator#buildAdvisors

	protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
		// Handle prototypes correctly...
		// 解析注册的所有InterceptorName
		Advisor[] commonInterceptors = resolveInterceptorNames();

		List<Object> allInterceptors = new ArrayList<>();
		if (specificInterceptors != null) {
			if (specificInterceptors.length > 0) {
				// specificInterceptors may equals PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
				// 加入当前切面类的拦截器
				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.isTraceEnabled()) {
			int nrOfCommonInterceptors = commonInterceptors.length;
			int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
			logger.trace("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对象
			advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
		}
		return advisors;
	}

将拦截器转换为Advisors

因为spring中有各种增强器、增强方法、拦截器等等方式对逻辑进行增强,所有有必要统一封装为Advisor,方便后续处理。


	@Override
	public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
		if (adviceObject instanceof Advisor) {
			// 如果本身就是Advisor 无需处理直接返回
			return (Advisor) adviceObject;
		}
		// 如果不是Advice类型,抛出异常
		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.
			// MethodInterceptor 使用 DefaultPointcutAdvisor封装
			return new DefaultPointcutAdvisor(advice);
		}
		// 如果存在Advisor的适配器那么也同样需要进行封装
		for (AdvisorAdapter adapter : this.adapters) {
			// Check that it is supported.
			if (adapter.supportsAdvice(advice)) {
				return new DefaultPointcutAdvisor(advice);
			}
		}
		throw new UnknownAdviceTypeException(advice);
	}

创建代理

在DefaultAopProxyFactory#createAopProxy这个方法中决定采用JDK动态代理还是CGLIB代理。判断条件如下

  • optimize:控制通过CGLIB创建的代理是否使用激进的优化策略
  • proxyTargerClass:是否采用目标类本身代理,也就是如果设置为 ture,就采用CGLIB代理
  • hasNoUserSuppliedProxyInterfaces:是否存在代理接口
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// 创建代理
		return getAopProxyFactory().createAopProxy(this);
	}

	@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		// 根据这三个条件 决定使用JDK动态代理 还是CGLIB代理
		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动态代理实现和CGLIB代理实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值