spring5.0源码解析 Aop 02

建立 AopProxy对象

设计原理

在spring 的 Aop模块中,是通过配置和调用Spring的ProxyFactoryBean来完成这个任务的,在 ProxyFactoryBean 中,封装了主要代理对象的生成过程,这个过程由JDK的Proxy和CGLibL两种方式实现

在这里插入图片描述
在这个 类继承关系中,可以看到完成 AOP应用的类,比如AspectJProxyFactory、TransactionProxyFactoryBean , 具体的对象的生成分别由 ProxyFactoryBean,AspectJProxyFactory和ProxyFactory来完成,**ProxyFactoryBean和ProxyFactory都提供了AOP功能的封装,只是使用ProxyFactoryBean可以在Ioc容器中完成声明式配置,而是用ProxyFactory 则需要编程式使用Aop的功能

ProxyConfig

用于创建代理的配置的方便超类,以确保所有代理创建者具有一致的属性

	// 是否直接代理目标类,为不是代理特定的接口
	private boolean proxyTargetClass = false;

	// 标记是否对代理进行优化。启动优化通常意味着在代理对象被创建后,增强的修改将不会生效,因此默认值为false。
	private boolean optimize = false;

	//该属性用于空值生成的代理对象是否可以强制转型为Advised,默认值为false,表示任何生成的代理对象都可以强制转换成Advised,true是不可以,可以通过Adviced查询代理对象的一些状态
	boolean opaque = false;

	// 标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。
	// 当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。
	boolean exposeProxy = false;

	// 标记该配置是否需要被冻结,如果被冻结,将不可以修改增强的配置。
	// 如果该值为true,那么代理对象的生成的各项信息配置完成,则不容许更改,如果ProxyFactory设置完毕,该值为true,则不能对Advice进行改动,可以优化代理对象生成的性能。默认情况下该值为false
	private boolean frozen = false;

AdvisedSupport

可以将他看成其子类创建Aop代理对象的一个辅助类。

配置当前代理的Adivsiors
配置当前代理的目标对象
配置当前代理的接口
提供getInterceptorsAndDynamicInterceptionAdvice方法用来获取对应代理方法对应有效的拦截器链

ProxyFactoryBean

getObject返回此工厂Aop代理实例

ProxyFactoryBean 实现了 FactoryBean getObject返回此工厂Aop代理实例

// 创建此工厂返回的AOP代理实例。
	@Override
	@Nullable
	public Object getObject() throws BeansException {
		// 初始化通知器链
		initializeAdvisorChain();
		// 这里对singleton和prititype类型进行了区分,生成对象的proxy
		if (isSingleton()) {
			return getSingletonInstance();
		}
		else {
			if (this.targetName == null) {
				logger.info("Using non-singleton proxies with singleton targets is often undesirable. " +
						"Enable prototype proxies by setting the 'targetName' property.");
			}
			return newPrototypeInstance();
		}
	}

proxyFactory

在专栏前面的文章介绍了 使用ProxyFactoryBean 实现获取Aop代理对象。 ProxyFactoryBean 与 proxyFactory 的实现原理是一样的 ,不过是对 拦截器、切入点进行整合,通过递归的形式生成代理对象的过程,只是他们两个在最外层的表现上有所不同。

proxyFactory 是 ProxyCreatorSupport 的子类,proxyFactory 获取代理对象也是通过 getProxy方法为入口,由 getAopProxyFactory 完成 , 而 ProxyCreatorSupport 也继承了 AdvisedSupport 具有了 通知和切入点的支持

	public <T> T getProxy() {
		return (T) createAopProxy().getProxy();
	}
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// getAopProxyFactory 获取的是 DefaultAopProxyFactory 对象
		return getAopProxyFactory().createAopProxy(this);
	}

AspectProxyFactory、 proxyFactory 、 ProxyFactoryBean 的区别

在这里插入图片描述

  • proxyFactory 这种是硬编码的方式,可以脱离spring直接使用。
  • AspectProxyFactory 实现了 @AspectJ 注解的形式 我们只需要配置切面、通知、切点表达式就能自动的实现切入的效果
  • ProxyFactoryBean 是创建AOP的最基本的方式。是将我们的AOP和IOC融合起来,而ProxyFactory 则是只能通过代码硬编码进行编写 一般都是给spring自己使用。
initializeAdvisorChain 初始化通知链
// 初始化通知链
	private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
		// 判断是否初始化过 , 通知链只出初始化一次
		if (this.advisorChainInitialized) {
			return;
		}

		if (!ObjectUtils.isEmpty(this.interceptorNames)) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
						"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
			}

			// Globals can't be last unless we specified a targetSource using the property...
			if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
					this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
				throw new AopConfigException("Target required after globals");
			}

			// Materialize interceptor chain from bean names.
			// 从bean名称具体化拦截器链。
			for (String name : this.interceptorNames) {
				// 如果拦截器name 以  * 号结尾
				if (name.endsWith(GLOBAL_SUFFIX)) {
					if (!(this.beanFactory instanceof ListableBeanFactory)) {
						throw new AopConfigException(
								"Can only use global advisors or interceptors with a ListableBeanFactory");
					}
					addGlobalAdvisors((ListableBeanFactory) this.beanFactory,
							name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
				}

				else {
					// If we get here, we need to add a named interceptor.
					// We must check if it's a singleton or prototype.
					//需要添加一个命名拦截器。必须检查它是单体还是原型。
					Object advice;
					if (this.singleton || this.beanFactory.isSingleton(name)) {
						// Add the real Advisor/Advice to the chain.
						advice = this.beanFactory.getBean(name);
					}
					else {
						// It's a prototype Advice or Advisor: replace with a prototype.
						// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
						advice = new PrototypePlaceholderAdvisor(name);
					}
					//将给定的advice, advisor或对象添加到拦截器列表中。
					addAdvisorOnChainCreation(advice);
				}
			}
		}

		this.advisorChainInitialized = true;
	}
getSingletonInstance 生成单例的代理对象

getSingletonInstance 这个方法是 proxyFactoryBean生成AopProxy代理对象的调用接口。代理对象会封装对target目标对象的调用,也就是说针对target对象的调用行为会被这里生成的代理对象所拦截,

// 返回这个类的代理对象的单例实例,如果尚未创建,则延迟创建。
	private synchronized Object getSingletonInstance() {
		if (this.singletonInstance == null) {
			// 被代理的目标对象
			this.targetSource = freshTargetSource();
			if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
				// Rely on AOP infrastructure to tell us what interfaces to proxy.
				// 依靠AOP基础设施告诉我们代理的接口。
				Class<?> targetClass = getTargetClass();
				if (targetClass == null) {
					throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
				}
				// 设置代理对象的接口
				setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
			}
			// 初始化共享单例实例。
			super.setFrozen(this.freezeProxy);
			// 生成具体的代理对象
			this.singletonInstance = getProxy(createAopProxy());
		}
		return this.singletonInstance;
	}
	// 获取代理对象
protected Object getProxy(AopProxy aopProxy) {
		return aopProxy.getProxy(this.proxyClassLoader);
	}

AopProxy

spring 利用 AopProxy 接口类把Aop代理对象的实现与框架其他部分有效的分开,他有两个子类 CglibAopProxy 和 JdkDynamicAopProxy 分别采用 CGLIB和 JDK来生成代理对象。

生成 AopProxy 是通过 AopProxyFactory来实现的,至于生成什么样的代理对象封装在 AdvisedSupport 中,也是 ProxyFactoryBean 的父类

// 通过 AopProxyFactory 生成 AopProxy
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

DefaultAopProxyFactory.createAopProxy 方法 根据 AdvisedSupport 生成AopProxy 这里决定了使用CGLIB还是Jdk的的方式

@Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (!NativeDetector.inNativeImage() &&
				(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.");
			}
			// 如果targetClass是接口类,使用Jdk 来生成
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			// 使用Cglib 生成
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

在AopProxy代理对象生成过程中,首先要从AdvisedSupport对象中取得配置的目标对象,在完成目标对象的检查后,根据配置情况来决定使用什么方式来创建AopProxy代理对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1999

每人一点点,明天会更好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值