spring 深入了解bean的创建过程

目录

一、创建bean之初

1.盘点bean定义是否是bean工厂

2.规范的bean name

3.合并bean定义

4:检查合并的bean定义

5:获取所有@DependsOn注解的依赖bean

二、创建bean实例

1.确保bean类已被实际解析

2:执行实现了InstantiationAwareBeanPostProcessor的后置处理器

3:实例化bean

4:将 MergedBeanDefinitionPostProcessors 应用于指定的 bean 定义(后置处理器调用)

5:属性赋值

6:初始化bean

四:销毁

1:注册销毁方法 registerDisposableBeanIfNecessary

五:总结草图

六 :补充说明

1:spring 如何确定使用哪种构造器实例化bean?

2:初始化bean的方式有几种?







一、创建bean之初

           spring调用 beanFactory.preInstantiateSingletons()此方法完成整个bean生产以及依赖注入,那么在生成bean之前,spring做了哪些事呢?

1.判断bean定义是否是bean工厂

     遍历所有beandefinition 非懒加载以及非抽象bean,单例,去执行AbstractBeanFactory.isFactoryBean(beanName) 方法判断是否是重写 SmartFactoryBean接口的isEagerInit方法为true,若设置为true,就会先去创建bean实例
public void preInstantiateSingletons() throws BeansException {
        ......
	if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
		isEagerInit = AccessController.doPrivileged(
				(PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit,
				getAccessControlContext());
	}
	else {
		isEagerInit = (factory instanceof SmartFactoryBean &&
				((SmartFactoryBean) factory).isEagerInit());
	}
	if (isEagerInit) {
		getBean(beanName);
	}
        ......
}

2.获取规范的bean name

        调用 transformedBeanName 返回实际的 bean 名称,去掉工厂取消引用前缀(如果有,也去掉重复的工厂前缀)。

public static String transformedBeanName(String name) {
		Assert.notNull(name, "'name' must not be null");
		if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
			return name;
		}
		return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
			do {
				beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
			}
			while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
			return beanName;
		});
	}

3.合并bean定义

  调用 AbstractBeanFactory.getMergedBeanDefinition 方法
  如果给定bean的定义是子bean定义,则通过与父bean合并,返回另外给定bean的RootBeanDefinition。使用递归处理继承父bean定义,子bean的属性覆盖父bean的属性,并将当前bean的属性保存到缓存mergedBeanDefinitions中
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// 一次性bean实例:一次性实例的bean名称。
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null && !mbd.stale) {
			return mbd;
		}
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

4:检查合并的bean定义

    检查是否是设置了抽象bean的属性 在xml的配置bean可以设置抽象bean
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, @Nullable Object[] args)
			throws BeanDefinitionStoreException {

		if (mbd.isAbstract()) {
			throw new BeanIsAbstractException(beanName);
		}
	}

5:获取所有@DependsOn注解的依赖bean

        调用方法 mbd.getDependsOn() 获取在创建bean定义时已设置的依赖bean,并提前生成bean实例。

        缓存到dependentBeanMap中便于下次使用直接返回。

// 保证初始化当前bean所依赖的bean。(循环依赖问题)
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
	for (String dep : dependsOn) {
		if (isDependent(beanName, dep)) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
		}
		registerDependentBean(dep, beanName);
		try {
			//创建依赖bean
			getBean(dep);
		}
		catch (NoSuchBeanDefinitionException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
		}
	}
}

6:确定bean是否是单例或者多例

        单例则会调用 getSingleton 方法实现缓存(三级缓存)解决循环依赖问题,再调用钩子方法 调用createBean方法执行创建bean。

        非单例bean,会直接调用createBean方法执行创建bean

if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			 
		}
	});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
	 
	Object prototypeInstance = null;
	try {
		beforePrototypeCreation(beanName);
		prototypeInstance = createBean(beanName, mbd, args);
	}
	finally {
		afterPrototypeCreation(beanName);
	}
	bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

二、创建bean实例


1.确保bean类已被实际解析

           在 resolveBeanClass 方法判断是否已存在 BeanClass ,有直接返回,反之,调用 doResolveBeanClass方法  获取类加载器 加载类返回

           调用getDefaultClassLoader方法 获取ClassLoader,先获取Tomcat设置的线程的类加载器,没有找到就获取ClassUtils.class类的类加载器,还没有就获取应用的类加载器

public static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			cl = Thread.currentThread().getContextClassLoader();
		}
		catch (Throwable ex) {
			// 无法访问线程上下文 ClassLoader - 回退...
		}
		if (cl == null) {
			// 无线程上下文类加载器 -> 使用此类的类加载器。
			cl = ClassUtils.class.getClassLoader();
			if (cl == null) {
				// getClassLoader() 返回 null 表示引导类加载器
				try {
					cl = ClassLoader.getSystemClassLoader();
				}
				catch (Throwable ex) {
					//无法访问系统类加载器 - 哦,好吧,也许调用者可以忍受空...
				}
			}
		}
		return cl;
	}

spring的备注:

        返回要使用的默认类加载器:通常是线程上下文类加载器,如果可用;加载 ClassUtils 类的 ClassLoader 将用作后备。

        prepareMethodOverrides 判断方法是否有重载状态 默认为rue

2:执行实现了InstantiationAwareBeanPostProcessor的后置处理器

hasInstantiationAwareBeanPostProcessors   确定是否已注册InstantiationAwareBeanPostProcessor类型的beanPostProcessor,此接口实现实例化前的后置处理器。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 确保bean类在这一点上被实际解析。
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//调用 InstantiationAwareBeanPostProcessor->postProcessBeforeInstantiation
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						//调用 InstantiationAwareBeanPostProcessor->postProcessAfterInitialization
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

3:实例化bean

     1.确认是否解析beanClass

     2.判断多种条件确认使用那种构造器实例化bean,实例化方法分 autowireConstructor和instantiateBean(默认),spring需要去推断如何去实例化bean,逻辑比较复杂!!!

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 确保bean类在这一点上被实际解析。
		Class beanClass = resolveBeanClass(mbd, beanName);
 
		Supplier instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		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);
			}
		}

		// 指定实例化的构造器
		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);
		}

		// 无需特殊处理:只需不使用arg构造函数。
		return instantiateBean(beanName, mbd);
	}

4:将 MergedBeanDefinitionPostProcessors 应用于指定的 bean 定义(后置处理器调用)

        调用 applyMergedBeanDefinitionPostProcessors 遍历所有的beanPostProcessors执行MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition,

        作用:修改合并的bean定义属性

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

5:属性赋值

        执行  populateBean(beanName, mbd, instanceWrapper) 方法,使用bean定义中的属性值填充给定BeanWrapper中的bean实例。

        populateBean方法内会先执行 实例化后的后置处理器 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

       接下来spring会处理配置了ByType和ByName的属性,实现属性注入。此注入是spring自带的实现。代码如下:

if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// 如果适用,根据名称添加基于自动装配的属性值。
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// 如果适用,根据类型添加基于自动装配的属性值。
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

       最后确认是否存在 InstantiationAwareBeanPostProcessor的属性后置处理器,并执行后置处理器,实现spring扩展。代码如下:

if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}

6:初始化bean

        执行 initializeBean方法,应用给定的属性值,解析对该bean工厂中其他bean的任何运行时引用。必须使用深度复制,因此spring不会永久修改此属性。

        首先执行 invokeAwareMethods方法确定是否实现Aware接口,并处理相关的属性设置,代码如下:

private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

        执行初始化前后置处理器 BeanPostProcessor.postProcessBeforeInitialization(result, beanName),如后置处理器有返回,直接返回bean实例

        接下来执行初始化方法invokeInitMethods(beanName, wrappedBean, mbd)

        最后执行初始化后后置处理器,完成bean实例初始化。代码如下:

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

四:销毁

1:注册销毁方法 registerDisposableBeanIfNecessary

        此方法会执行 DestructionAwareBeanPostProcessor的后置处理器

五:总结草图

spring 深入了解bean的创建过程_第1张图片

六 :补充说明

1:spring 如何确定使用哪种构造器实例化bean?

      1,遍历所有的beanPostProcessors,调用实现了 SmartInstantiationAwareBeanPostProcessor接口的 determineCandidateConstructors方法。

        此处可以自定义用于给定 bean 的候选构造函数的处理,可参考spring中AutowiredAnnotationBeanPostProcessor类中对于determineCandidateConstructors方法的实现。

 代码实现如下:

protected Constructor[] determineConstructorsFromBeanPostProcessors(@Nullable Class beanClass, String beanName)
			throws BeansException {

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

        2:spring推断获取构造函数

        掉用 BeanUtils.findPrimaryConstructor(clazz) 方法获取主构造函数,若没有找到,执行clazz.getConstructors()方法去找合适的构造函数(?) ,代码实现如下:

public Constructor[] getPreferredConstructors() {
			Class clazz = getBeanClass();
			//返回所提供类的主构造函数
			Constructor primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
			if (primaryCtor != null) {
				return new Constructor[] {primaryCtor};
			}
			Constructor[] publicCtors = clazz.getConstructors();
			if (publicCtors.length > 0) {
				return publicCtors;
			}
			return null;
		}

        3:以上都没有获取到构造函数就使用默认构造函数实例化给定的bean,代码实现如下:

	protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
	 
			Object beanInstance;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(
						(PrivilegedAction) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
						getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		 
	 
	} 
   
  

2:初始化bean的方式有几种?

        1:继承InitializingBean的接口,并实现 afterPropertiesSet方法实现,spring代码实现如下:

boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		 
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		} 
   
  

        2:通过@bean或者XML标签中有设置initMethod属性,spring代码实现如下:

if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}


 

你可能感兴趣的:(java,spring,spring,java,后端)