欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring-framework5.0.2 源码阅读笔记 - AOP切面(代理类创建阶段)

程序员文章站 2022-06-19 15:21:53
Spring AOP 代理类创建阶段注意: 本片博客所展示的代码中,删除了对核心流程以外的代码,为了不影响观看,所以只保留了最核心的代码spring 初始化时序图 (免费克隆)Spring-framework 5.0.2 中文注释源码下载闲聊AOP 是我们熟知的概念,但却显得特别的陌生,甚至 OOP 有些时候概念都特别的模糊。在 WEB项目开发中,AOP 基本上是一个老生常谈的问题,面试的频率也极为频繁。在了解 AOP 之前,先聊聊动态代理,以 JDK 为例,首先代理类,需要实现 Invo...

Spring AOP 代理类创建阶段

注意: 本片博客所展示的代码中,删除了对核心流程以外的代码,为了不影响观看,所以只保留了最核心的代码

spring 初始化时序图 (免费克隆)
Spring-framework 5.0.2 中文注释源码下载

闲聊

AOP 是我们熟知的概念,但却显得特别的陌生,甚至 OOP 有些时候概念都特别的模糊。在 WEB项目开发中,AOP 基本上是一个老生常谈的问题,面试的频率也极为频繁。在了解 AOP 之前,先聊聊动态代理,以 JDK 为例,首先代理类,需要实现 InvocationHandler 接口,来标志这个类是代理类,并且实现其内部的 invoke() 方法,只要在此基础上,使用 Proxy#newProxyInstance() 来生成一个代理类,那么最终在使用生成的代理类的时候,就会调用实现 InvocationHandler#invoke() 来完成动态代理

public class JdkDynamicProxy implements InvocationHandler {

    private IPerson target;
	// 通过该方法,获取一个 IPerson 实现类的一个代理类
    public IPerson getInstance(IPerson target) {
        this.target = target;
        Class<? extends IPerson> clazz = target.getClass();
        // 生成代理类
        return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }
    // 执行代理类的方法,如果接口中有多个方法,那么这个invoke 将会被执行多次
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        after();
        Object invoke = method.invoke(this.target, args);
        before();
        return invoke;
    }

    private void before() {
        System.out.println("前置方法被执行");
    }

    private void after() {
        System.out.println("后置方法被执行");
    }
}

下面通过本片文章的解读,彻底了解 Spring AOP 的源码和过程。紧接着上一篇文章 《依赖注入》

1. 入口

在以上的描述中,动态代理的实现方式明白了后,开始进入 AOP 正题。首先我们要找到 AOP 的入口,在查阅各种资料后,统一指向了 BeanPostProcessor 类,当然的的确确该类就是 AOP 的入口,该类可以理解为是一个 bean 的监听器,bean 注入到容器后,bean 就具备了 IOC 容器的回调能力,这样就能触发动态代理。

BeanPostProcessor 类中,定义了两个抽象方法,两个方法都是与 spring bean 生命周期紧密相关的,所以 AOP 与 是在 DI 过程中被触发的

  1. postProcessBeforeInitialization()
  2. postProcessAfterInitialization()
public interface BeanPostProcessor {

	//为在Bean的初始化前提供回调入口
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	//为在Bean的初始化之后提供回调入口
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

2. 为 bean 添加 BeanPostProcess 后置处理器

bean 添加后置处理器,是在 bean 被实例化,并对属性注入后完成的。通过对依赖注入部分的解读,我们知道当 bean 的属性是 lazy-init = true 的时候,调用 BeanFactory#getBean() 才会触发 bean 的初始化并对属性进行注入的过程。根进源码,会发现真正实现 bean 初始化和属性注入的类是在 AbstractAutowireCapableBeanFactory#doCreateBenan()中。在该方法中,调用本类的 initalizeBean(),调用这个方法,则是对 bean 的后置处理器进行添加,AOP 就是在这个方法里面被完成的

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	Object exposedObject = bean;
	try {
		populateBean(beanName, mbd, instanceWrapper);
		// **************************************************//
		// 这里就是对 BeanPostProcess 进行添加的
		// **************************************************//
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
				}
			}
		}
	}

	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

initalizeBean() 如下:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	//JDK的安全机制验证权限
	if (System.getSecurityManager() != null) {
		//实现PrivilegedAction接口的匿名内部类
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		//为Bean实例对象包装相关属性,如名称,类加载器,所属容器等信息
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	//对BeanPostProcessor后置处理器的postProcessBeforeInitialization
	//回调方法的调用,为Bean实例初始化前做一些处理
	if (mbd == null || !mbd.isSynthetic()) {
		// 调用BeanPostProcessor#postProcessBeforeInitialization(), 完成Bean的初始化前提供回调入口
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	//调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置
	//文件中通过init-method属性指定的
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
	}
	//对BeanPostProcessor后置处理器的postProcessAfterInitialization
	//回调方法的调用,为Bean实例初始化之后做一些处理
	if (mbd == null || !mbd.isSynthetic()) {
		// 调用BeanPostProcessor#postProcessBeforeInitialization(), 完成Bean的初始化后提供回调入口
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

applyBeanPostProcessorsBeforeInitialization() 如下:

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
	throws BeansException {
	Object result = existingBean;
	//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		//调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在
		//初始化之前做一些自定义的处理操作
		Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

applyBeanPostProcessorsAfterInitialization() 如下:

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {
	Object result = existingBean;
	//遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		//调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在
		//初始化之后做一些自定义的处理操作
		Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

在以上方法中,已经寻找到了 bean 初始化前添加的后置处理器和 bean 初始化后添加的后置处理器,但是 BeanPostProcessor 接口类的实现类很多,本文章中主要从 AbstractAutoProxyCreator 入手,该类主要重写了父类的 postProcessAfterInitialization(),而在 postProcessBeforeInitialization() 直接返回了当前 bean,那么直接进入 postProcessAfterInitialization() 中看源码,如下:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		// 查看是否被子类所标记,如果被标记了,则表明该bean 需要被创建代理对象
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

该方法中,主要是查看该类是否被子类标记,是否在缓存中存在当前这个 bean 需要被代理,如果存在则进入下面的方法中:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	// 验证 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.
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	// DO_NOT_PROXY = 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());
		// 返回得到的代理 bean 
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

那么通过以上注释的内容,可以大致了解到,经过一系列的验证,直至该类确定需要代理,则会给该类创建一个代理类,核心方法就是 createaProxy(),那么请移步至该方法中,源码如下:

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
	// 如果创建该的工厂是 则给bean执行公开的目标类
	if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
		AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
	}
	// new 创建出代理的工厂
	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);
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	customizeProxyFactory(proxyFactory);

	proxyFactory.setFrozen(this.freezeProxy);
	if (advisorsPreFiltered()) {
		proxyFactory.setPreFiltered(true);
	}
	// 通过代理工厂创建代理对象
	return proxyFactory.getProxy(getProxyClassLoader());
}

跟进整段方法,最终调用了 ProxyFactory#getProxy() 方法,那么就进入该方法做了什么事情呗,源码如下:

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

那么,这里是调用了两个方法,我们先进入 createAopProxy(),我觉得这里应该就是选择 JDK 还是 CGLIB 的动态代理工具了

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

// 工厂接口
public interface AopProxyFactory {
	// 创建一个 AOP 动态代理的实例,从 JDK 和 CGLIB 中选择
	AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}

// 工厂实现类,目前只有一个实现类
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) {
				...
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
  .....
}

这里就很清晰了,如果目标类是 interface 类型或者是 只使用 getProxyClass() 或者 newProxyInstance()时,使用 JDK 动态代理,否则就是用 CGLIB 动态代理。回到 ProxyFactory#getProxy() 方法中,首先进入到的是 AopProxy 接口中,这个接口主要由 JdkDynamicAopProxyCglibAopProxy 实现,那么先进入我们熟知的 JDK 动态代理中吧!源码如下:

public Object getProxy(@Nullable 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);
}

Jdk 动态代理看完了,那么进入 Cglib 中看看,源码如下:

public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating CGLIB proxy: target source is " + 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);

		// Configure CGLIB 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
		enhancer.setCallbackFilter(new ProxyCallbackFilter(
				this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
		enhancer.setCallbackTypes(types);

		// Generate the proxy class and create a proxy instance.
		return createProxyClassAndInstance(enhancer, callbacks);
	}
	catch (CodeGenerationException | IllegalArgumentException ex) {
	}
	catch (Throwable ex) {
		// TargetSource.getTarget() failed
		throw new AopConfigException("Unexpected AOP exception", ex);
	}
}

// 最终返回代理对象是在这里诞生的
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
	enhancer.setInterceptDuringConstruction(false);
	enhancer.setCallbacks(callbacks);
	return (this.constructorArgs != null && this.constructorArgTypes != null ?
			// 那么 直接调用 create() 即可
			enhancer.create(this.constructorArgTypes, this.constructorArgs) :
			enhancer.create());
}

3. 回头总结

写了这么多,先抽根烟来,等我一会儿!!
我又会来了!!!
那么,经过上面这么一番操作后,可以看出,在 AOP 创建代理类整个阶段,就已经完毕了。说到底,如果类被标记为需要创建动态代理的类,那么给与其创建动态代理的类,替换掉 IOC 原有的 bean,因为原有的 bean 不具备 后置处理回调功能。那么创建代理的方式选择,则是使用了静态的工厂模式,ProxyFactory 对类的类型进行判断进行选择创建。
下一篇会解读 AOP 被发起回调后的逻辑。

本文地址:https://blog.csdn.net/qq_38800175/article/details/109525743