spring aop代理对象的产生(一)

准备

接口

public interface UserService {
    
    
    String query();
}

接口的实现

@Service
public class UserServiceImpl implements UserService {
    
    

    @Override
    public String query() {
    
    
        System.out.println("------------ yz ------------");
        return "yz";
    }
}

切面类

@Aspect
@Component
public class AopConfig {
    
    

    @Pointcut(value = "execution(* com.atguigu.springIOC.UserServiceImpl.*(..))")
    public void businessService() {
    
    
    }

    @Before(value = "businessService()")
    public void doBefore() {
    
    
        System.out.println("----------------- doBefore -----------------");
    }

    @AfterReturning(value = "businessService()")
    public void doAfterReturning() {
    
    
        System.out.println("----------------- doAfterReturning -----------------");
    }

    @After(value = "businessService()")
    public void doAfter() {
    
    
        System.out.println("----------------- doAfter -----------------");
    }
}

测试类

// 该注解在测试时必须添加;在使用 springboot 较高版本启动运行程序时,可以不添加
@EnableAspectJAutoProxy
@ComponentScan(basePackages = {
    
    "com.atguigu.springIOC"})
public class BeanTest {
    
    

    public static void main(String[] args) {
    
    
        // 获取 spring IOC 容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);
        // 从容器中获取 bean
        UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
        String query = userService.query();
        System.out.println(query);
    }
}

测试结果

----------------- doBefore -----------------
------------ yz ------------
----------------- doAfter -----------------
----------------- doAfterReturning -----------------
yz

解读 spring aop 代理对象的产生

1.源码解读之前

既然要产生代理对象,我们进行源码分析,无非就是从下面两行代码入手

// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);
// 从容器中获取 bean
UserService userService = (UserService) applicationContext.getBean("userServiceImpl");

对于上面的代码的 getBean 方法,它的底层逻辑是首先会从一级缓存 singletonObjects 中获取,如果没有,再根据具体的 bean 的作用域分别去完成 bean 的初始化(不考虑循环依赖情况)

通过 spring 初始化 bean(单例) 过程 的文章分析,userServiceImpl(原型 bean) 这个 bean 会通过 getBean 方法从一级缓存 singletonObjects 中能获取到。那么 userServiceImpl(原型 bean) 的代理对象肯定从下面的代码中产生

// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);

2.抽象类 AbstractBeanFactorydoGetBean 方法

关于代码

// 获取 spring IOC 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanTest.class);

的过程,鉴于篇幅本篇文章不再详细赘述,详细过程请查看,我们从这个 doGetBean 方法开始

@SuppressWarnings("unchecked")
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
    

		/**
		 * 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两个原因
		 * 1、name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 本身,而非 FactoryBean
		 *   实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储
		 *   方式是一致的,即 <beanName, bean>,beanName 中是没有 & 这个字符的。所以我们需要
		 *   将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 实例。
		 * 2、还是别名的问题,转换需要 &beanName
		 */
		final String beanName = transformedBeanName(name);
		Object bean;

		// 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化
		Object sharedInstance = getSingleton(beanName);
		// 如果已经初始化过,直接从缓存中获取
		if (sharedInstance != null && args == null) {
    
    
			// 如果beanName的实例存在于缓存中
			if (logger.isDebugEnabled()) {
    
    
				if (isSingletonCurrentlyInCreation(beanName)) {
    
    
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
    
    
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
	
			/**
			 * 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
			 * sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
			 * bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
			 * 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
			 */
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
    
    
			// 如果是原型不应该在初始化的时候创建,在这里直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
    
    
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 获取parentBeanFactory
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    
    
				// 将别名解析成真正的beanName
				String nameToLookup = originalBeanName(name);
				// 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
				if (parentBeanFactory instanceof AbstractBeanFactory) {
    
    
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				// 尝试在parentBeanFactory中获取bean对象实例
				else if (args != null) {
    
    
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
    
    
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			if (!typeCheckOnly) {
    
    
				// 添加到alreadyCreated set集合当中,表示他已经创建过一次,做标记
				markBeanAsCreated(beanName);
			}

			try {
    
    
				// 根据beanName重新获取MergedBeanDefinition(步骤6将MergedBeanDefinition删除了,这边获取一个新的)
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 检查MergedBeanDefinition
				checkMergedBeanDefinition(mbd, beanName, args);

				// 拿到当前bean依赖的bean名称集合,在实例化自己之前,需要先实例化自己依赖的bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
    
    
					// 遍历当前bean依赖的bean名称集合
					for (String dep : dependsOn) {
    
    
						// 检查dep是否依赖于beanName,即检查是否存在循环依赖
						if (isDependent(beanName, dep)) {
    
    
						// 如果是循环依赖则抛异常
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 将dep和beanName的依赖关系注册到缓存中
						registerDependentBean(dep, beanName);
						try {
    
    
							// 获取dep对应的bean实例,如果dep还没有创建bean实例,则创建dep的bean实例
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
    
    
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// bean 的实例化
				if (mbd.isSingleton()) {
    
    
				// scope为 singleton 的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
					sharedInstance = getSingleton(beanName, () -> {
    
    
						try {
    
    
							// 创建Bean实例
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
    
    
							destroySingleton(beanName);
							throw ex;
						}
					});
					// 返回beanName对应的实例对象
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				
				else if (mbd.isPrototype()) {
    
    
					// scope为 prototype 的bean创建
					Object prototypeInstance = null;
					try {
    
    
						// 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
						beforePrototypeCreation(beanName);
						// 创建Bean实例
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
    
    
					// 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
						afterPrototypeCreation(beanName);
					}
					// 返回beanName对应的实例对象
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				else {
    
    
					// 既不是单例也不是原型的 bean创建,可能是 request之类的
					// 根据scopeName,从缓存拿到scope实例
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
    
    
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
    
    
					// 既不是单例也不是原型的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
						Object scopedInstance = scope.get(beanName, () -> {
    
    
						// 创建实例前的操作(将beanName保存到prototypesCurrentlyInCreation缓存中)
							beforePrototypeCreation(beanName);
							try {
    
    
							// 创建bean实例
								return createBean(beanName, mbd, args);
							}
							finally {
    
    
								// 创建实例后的操作(将创建完的beanName从prototypesCurrentlyInCreation缓存中移除)
								afterPrototypeCreation(beanName);
							}
						});
						// 返回beanName对应的实例对象
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
    
    
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
    
    
				// 如果创建bean实例过程中出现异常,则将beanName从alreadyCreated缓存中移除
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// 检查所需类型是否与实际的bean对象的类型匹配
		if (requiredType != null && !requiredType.isInstance(bean)) {
    
    
			try {
    
    
			// 类型不对,则尝试转换bean类型
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
    
    
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
    
    
				if (logger.isDebugEnabled()) {
    
    
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
}

注意下面的代码,第一次(启动初始化 IOC 容器时 )sharedInstance 肯定为 null

// 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化
Object sharedInstance = getSingleton(beanName);

3.由于 userServiceImpl(原型 bean)是单例的,所以我们重点关注:

// bean 的实例化
if (mbd.isSingleton()) {
    
    
		// scope为 singleton 的bean创建(新建了一个ObjectFactory,并且重写了getObject方法)
	sharedInstance = getSingleton(beanName, () -> {
    
    
		try {
    
    
			// 创建Bean实例
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
    
    
			destroySingleton(beanName);
			throw ex;
		}
	});
	// 返回beanName对应的实例对象
	// 这里主要处理实现了FactoryBean的情况,需要调用重写的getObject()方法来获取实际的Bean实例
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

4.在这里使用 idea 条件断点进行代码调试,在下面这行打断点

sharedInstance = getSingleton(beanName, () -> {
    
     

在这里插入图片描述
进入 getSingleton 方法如下图:

在这里插入图片描述
5.重新打条件断点,进入 singletonFactory.getObject() 方法

在这里插入图片描述
6.来到 AbstractAutowireCapableBeanFactorycreateBean 方法

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    
    
	
	if (logger.isDebugEnabled()) {
    
    
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	// 确保对应BeanClass完成解析,具体表现是进行了ClassLoder.loadClass或Class.forName完成了类加载
	resolveBeanClass(mbd, beanName);

	try {
    
    
	    // 准备方法覆盖,主要为lookup-method,replace-method等配置准备
		mbd.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
    
    
		throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
    
    
		// 供特定后置处理器拓展,如果直接生成了一个Bean,就直接返回不走正常创建流程。
		// 具体逻辑是判断当前Spring容器是否注册了实现了InstantiationAwareBeanPostProcessor接口的后置处理器
		// 如果有,则依次调用其中的applyBeanPostProcessorsBeforeInstantiation方法,如果中间任意一个方法返回不为null,直接结束调用。
		// 然后依次所有注册的BeanPostProcessor的postProcessAfterInitialization方法(同样如果任意一次返回不为null,即终止调用。
		Object bean = resolveBeforeInstantiation(beanName, mbd);
		// 如果不为空,说明提前生成了实例,直接返回
		if (bean != null) {
    
    
			return bean;
		}
	}
	catch (Throwable ex) {
    
    
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

    // 具体创建Bean逻辑
	Object beanInstance = doCreateBean(beanName, mbd, args);
	if (logger.isDebugEnabled()) {
    
    
		logger.debug("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}

断点调试发现,下面会产生代理对象,继续追踪

// 具体创建Bean逻辑
Object beanInstance = doCreateBean(beanName, mbd, args);

7.来到了 AbstractAutowireCapableBeanFactorydoCreateBean 方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
    
    

		// BeanWrapper封装了具体的Bean实例,然后可以很方便地通过调用getPropertyValue和setPropertyValue等方法反射读写Bean的具体属性
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
    
    
			// 先尝试从缓存中取
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
    
    
			// 调用构造方法创建一个空实例对象,并用BeanWrapper进行包装
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
    
    
			mbd.resolvedTargetType = beanType;
		}

		// 获取所有的后置处理器,如果后置处理器实现了MergedBeanDefinitionPostProcessor接口,则一次调用其postProcessMergedBeanDefinition方法
		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) {
    
    
			if (logger.isDebugEnabled()) {
    
    
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
	
			/**
			 * 循环依赖处理逻辑:将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的 bean 添加到三级缓存 singletonFactories 中
			 * 具体内部会遍历后置处理器,判断是否有SmartInstantiationAwareBeanPostProcessor的实现类,然后调用里面getEarlyBeanReference覆盖当前Bean
		 	 * 默认不做任何操作返回当前Bean,作为拓展,这里比如可以供AOP来创建代理类
			 */
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 开始对Bean实例进行初始化
		Object exposedObject = bean;
		try {
    
    
			// 对bean进行属性填充,在这里面完成依赖注入的相关内容
			populateBean(beanName, mbd, instanceWrapper);
			// 完成属性依赖注入后,进一步初始化Bean
		    // 具体进行了以下操作:
		    // 1.若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
		    // 2.遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
		    // 3.如果实现了initialzingBean,调用实现的 afterPropertiesSet()
		    // 4.如果配置了init-mothod,调用相应的init方法
		    // 5.遍历后置处理器,调用实现的postProcessAfterInitialization
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
    
    
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
    
    
				throw (BeanCreationException) ex;
			}
			else {
    
    
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", 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()) {
    
    
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// 如果实现了Disposable接口,会在这里进行注册,最后在销毁的时候调用相应的destroy方法
		try {
    
    
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
    
    
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
}

8.在 doCreateBean 方法中会产生代理对象的代码(注意:代理对象的产生是在实例化 beanbean 的属性填充之后进行的):

exposedObject = initializeBean(beanName, exposedObject, mbd);

doCreateBean(beanName, mbd, args) 的主要方法流程:

  1. createBeanInstance(beanName, mbd, args)实例化 bean,调用对象的构造方法实例化对象
  2. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName,mbd, bean)):将已完成实例化,但是未完成属性赋值和相关的初始化的一个不完整的 bean 添加到三级缓存 singletonFactories
  3. populateBean(beanName, mbd, instanceWrapper)bean 进行属性填充
  4. initializeBean(beanName, exposedObject, mbd)完成属性依赖注入后,进一步初始化 bean,在此过程中产生代理对象

9.进入 AbstractAutowireCapableBeanFactoryinitializeBean 方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    
    
		
		// 第一步:先执行所有的AwareMethods
		if (System.getSecurityManager() != null) {
    
    
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    
    
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		} else {
    
    
			// 如果实现了Aware接口,就对该bean进行一些设置
        	// 比如实现了BeanNameAware接口,那么对其bean的属性beanName上设置对应的beanName
        	// 如果实现了BeanFactoryAware接口,那么对其beanFactory属性设置上创建该bean使用的bean工厂
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
    
    
			// 执行所有的BeanPostProcessor#postProcessBeforeInitialization  初始化之前的处理器方法
			// 规则:只要谁反悔了null,后面的就都不要执行了
			// 这里面实现postProcessBeforeInitialization 的处理器就很多了,有很多对Aware进行了扩展的
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
    
    
			// 如果bean实现了InitializingBean或者用户自定义的init方法方法,那么调用这些初始化方法对bean的属性进行一些个性化设置
			invokeInitMethods(beanName, wrappedBean, mbd);
		} catch (Throwable ex) {
    
    
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
    
    
			// 执行后置处理器的postProcessAfterInitialization方法。AOP的原理和实现就在其中
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
}

9.1initializeBean 方法流程步骤

  1. 调用各类感知 Aware 接口
  2. 执行 applyBeanPostProcessorsBeforeInitialization 初始化前的处置操作
  3. 调用 InitializingBean 接口初始化 (如果配置了method-init,则调用其方法初始化 )
  4. 调用 applyBeanPostProcessorsAfterInitialization 初始化之后的处置操作,AOP 的原理和实现就在其中

代理对象产生主要流程步骤小结

  1. IOC 容器启动初始化时,首先会去一级缓存 singletonObjects 中去获取(肯定没有)
  2. 在根据当前 bean 的具体作用域,去初始化 bean
  3. 在做完 bean 的一些校验之后,会调用 createBeanInstance 去实例化 bean
  4. 如果存在 bean 的循环依赖的情况,会将当前已实例化的 bean put 进三级缓存 singletonFactories
  5. 接着会进行 bean 的相关属性填充,注意此时还并没有产生代理对象
  6. 再接着会进行 bean 的初始化操作,调用 initializeBean 方法
  7. 后续更新查看

猜你喜欢

转载自blog.csdn.net/weixin_38192427/article/details/113486299