SpringIOC的加载过程

springboo 如果存在bean则注销重新注册_java


1、首先通过BeanDefinitionReader读取配置文件,得到完成的Bean定义对象BeanDefinition对象,此时只是得到Bean的相关定义信息,还没有开始实例化Bean

2、上图中可以看出,当实现BeanFactoryPostProcessor时,可以对BeanDefination对象进行增强操作,并且当多个类实现接口时,可以重复进行增强,如下图所示

springboo 如果存在bean则注销重新注册_java_02


3、得到完成的BeanDefinition后就可以创建Bean对象了,包括从实例化->mergeBeanDefinition -> 属性填充 -> 初始化 -> 使用 -> 销毁一系列操作

SpringBean的生命周期

SpringBean的生命周期大致分为:实例化bean->属性填充->初始化bean->使用->销毁几个阶段,如下图所示

springboo 如果存在bean则注销重新注册_实例化_03

实例化

在实例化过程中,通过实现InstantiationAwareBeanPostProcessor接口,可以对准备进行实例化的Bean进行前置、后置和属性处理,对应实现接口如下:

/**
 * @author Aaron
 * @date 2023.03.10
 */
@Component
@Slf4j
public class BeanInstantiationDemo implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        log.warn("------BeforeInstantiation处理,此时Bean还未创建,需要拿到Class和beanName通过反射(大部分)创建对象\n当前beanClass为:{}\nbeanName为:{}\n------",beanClass,beanName);
        return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        log.warn("------AfterInstantiation处理,此时Bean已经被创建,所以可以那到当前Bean的信息------\n当前Bean为:{}\nbeanName为:{}",bean,beanName);
        return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        log.warn("对Bean属性值的设置:{}",pvs );
        return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
    }
}

启动时打印日志如下:

springboo 如果存在bean则注销重新注册_spring_04


从图中也可以看出,对BeanDefinition的增强在实例化前,而且对实例化的增强打印了多次,这是因为初始化的前置方法和后置方法是为所有 Bean 服务的,而非为某一个 Bean 服务的

Bean的实例化本质上就是选择构造函数然后使用反射创建对象,Bean创建时选择构造函数的代码在AbstractAutowireCapableBeanFactory.java#createBeanInstance中,具体代码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 再次解析BeanDefinition中的class,确保class已经被解析
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		// 是否提供了Supplier,如果提供,则使用Supplier进行实例化对象
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		// 是否提供了,工厂方法,如果提供,则使用工厂方法产生对象
		// 在configuration中标注@Bean的代码也会在此处被解析为FactoryMethod
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 创建相同Bean时的快捷方式
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		// 此处开始推断需要创建对象时的构造方法
		// 执行后置处理器,获取Bean的候选构造方法
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		// 需要自动注入的情况
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 首选的默认构造方法
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// 默认使用无参的构造方法
		return instantiateBean(beanName, mbd);
	}

经过查看,可以发现Spring推断构造函数的逻辑如下:

  1. 先判断是否提供Supplier,如果有则使用Supplier进行生产

最终调用实例化的代码如下:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			ReflectionUtils.makeAccessible(ctor);
			// 判断如果不是Kotlin类型则使用构造器的newInstance方法创建对象
			return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
					KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
		}
		catch (InstantiationException ex) {
			throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
		}
		catch (IllegalAccessException ex) {
			throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
		}
		catch (IllegalArgumentException ex) {
			throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
		}
		catch (InvocationTargetException ex) {
			throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
		}
	}