spring bean生命周期二---Spring Bean实例化( Instantiation)阶段

目录

一、这里涉及几个比较重要的后置处理器:

1、InstantiationAwareBeanPostProcessor :

2、martInstantiationAwareBeanPostProcessor 后置处理器:

3、SmartInstantiationAwareBeanPostProcessor后置处理器

4、InstantiationAwareBeanPostProcessor初始化后置处理器

二、Bean实例化详细流程

三、Spring Bean 实例化前阶段

第一次调用后置处理器

 3.1、自己实现 (这个在开发过程几乎用不到)

3.2、spring 内置的实现  (主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中)

四、Spring Bean 实例化阶段

4.1、第二次调用后置处理器推断构造方法 

4.2、instantiateBean(beanName, mbd)使用默认无参构造器实例化对象

4.3、使用依赖注入的构造器实例化对象:autowireConstructor(beanName, mbd, ctors, args)

五、处理合并BeanDefinition与解决循环依赖后置处理器

5.1、第三调用后置处理器MergedBeanDefinitionPostProcessor

5.2、第四次调用后置处理器 解决循环依赖提前暴露一个工厂

六、spring bean实例化后置阶段

6.1、第五次调用后置处理器 :属性是否注入InstantiationAwareBeanPostProcessor

6.2、测试实例 

总结:


经过上一篇的BeanDefinition 生成过程后,已经得到实例化bean的相关的源信息,这一篇重点介绍spring bean的实例化的过程,也就是我们通常的创建对象,不过这样需要推断构造器,使用反射实例化对象。

此阶段主要包括: Spring Bean 实例化前阶段、Spring Bean 实例化阶段、Spring Bean 实例化后阶段等阶段

 

一、这里涉及几个比较重要的后置处理器:

1、InstantiationAwareBeanPostProcessor :

  • Spring Bean 实例化前阶段:      第一次调用后置处理器   postProcessBeforeInstantiation 方法  默认实现是判断是否需要代理放入map中
  • Spring Bean  实例化后置阶段:   第五次调用后置处理器   postProcessAfterInstantiation方法          属性赋值(Populate)判断是否需要属性填充
  • populateBean属性赋值 :             第六次调用后置处理器:postProcessPropertyValues                为bean填充属性包括依赖注入的属性

2、martInstantiationAwareBeanPostProcessor 后置处理器:

        第二次调用后置处理器determineCandidateConstructors获取最优构造方法实例化对象

3、SmartInstantiationAwareBeanPostProcessor后置处理器

            第四次调用后置处理器getEarlyBeanReference解决循环依赖的问题

4、InstantiationAwareBeanPostProcessor初始化后置处理器

  • Spring Bean 初始化前阶段 postProcessBeforeInitialization
  • Spring Bean 初始化后阶段:postProcessAfterInitialization

    在实例化阶段主要涉及 1到3 后置处理器 如下图:

二、Bean实例化详细流程

相关入口:

  • 根据类型获取Bean
    org.springframework.context.support.AbstractApplicationContext.getBean(Class<T>)
  • 根据名字获取Bean
    org.springframework.context.support.AbstractApplicationContext.getBean(String)
  • 实际获取Bean
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
  • 根据给出的Bean获取真实Bean(可能是factoryBean)
    org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance
  • 创建Bean
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean
  • 实际创建Bean
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean

下面是 的相关源码

AbstractApplicationContext.finishBeanFactoryInitialization()实例化bean入口方法

 

//创建Bean实例对象
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 校验和准备Bean中的方法覆盖
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
			//TODO 第一次调用bean的后置处理器 主要判断bean需要被代理  bean一般都为空
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			//创建Bean的入口
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException ex) {
			// A previously detected exception with proper bean creation context already...
			throw ex;
		}
		catch (ImplicitlyAppearedSingletonException ex) {
			// An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry...
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

三、Spring Bean 实例化前阶段

第一次调用后置处理器

非主流生命周期 -- Bean 实例化前阶段:InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation

 3.1、自己实现 (这个在开发过程几乎用不到)

自己实现后置处理器的postProcessBeforeInstantiation 方法替换把配置完成的 superUser bean覆盖。重新生成一个superUser bean。

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

<!--    <context:annotation-config/>-->

<!--    <context:component-scan base-package="org.acme" />-->

    <!-- Root BeanDefinition 不需要合并,不存在 parent -->
    <!-- 普通 beanDefinition GenericBeanDefinition -->
    <!-- 经过合并后 GenericBeanDefinition 变成 RootBeanDefinition -->
    <bean id="user" class="org.geekbang.thinking.in.spring.ioc.overview.domain.User">
        <property name="id" value="1"/>
        <property name="name" value="小马哥"/>
        <property name="city" value="HANGZHOU"/>
        <property name="workCities" value="BEIJING,HANGZHOU"/>
        <property name="lifeCities">
            <list>
                <value>BEIJING</value>
                <value>SHANGHAI</value>
            </list>
        </property>
        <property name="configFileLocation" value="classpath:/META-INF/user-config.properties"/>
    </bean>

    <!-- 普通 beanDefinition GenericBeanDefinition -->
    <!-- 合并后 GenericBeanDefinition 变成 RootBeanDefinition,并且覆盖 parent 相关配置-->
    <!-- primary = true , 增加了一个 address 属性 -->
    <bean id="superUser" class="org.geekbang.thinking.in.spring.ioc.overview.domain.SuperUser" parent="user"
          primary="true">
        <property name="address" value="杭州"/>
    </bean>

   

</beans>
public class BeanInstantiationDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
        beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessorDome());
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        String location = "META-INF/dependency-lookup-context.xml";
        Resource resource = new ClassPathResource(location);
        // 指定字符编码 UTF-8
        EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
        beanDefinitionReader.loadBeanDefinitions(encodedResource);
        // 通过 Bean Id 和类型进行依赖查找
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        User superUser = beanFactory.getBean("superUser", User.class);
        System.out.println(superUser);

    }

    /**
     * 实现 后置处理器
     */
    static class  MyInstantiationAwareBeanPostProcessorDome implements InstantiationAwareBeanPostProcessor {

        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass)){
                //把配置完成的 superUser bean覆盖
                return  new SuperUser();
            }
            return null;//这里表示什么都不变化
        }
    }
}

执行日志。我们可以看到 SuperUser 只是实例化了 ,什么属性都没有填充

User{id=1, name='小马哥', city=HANGZHOU, workCities=[BEIJING, HANGZHOU], lifeCities=[BEIJING, SHANGHAI], configFileLocation=class path resource [META-INF/user-config.properties], company=null, context=null, contextAsText='null', beanName='user'}
SuperUser{address='null'} User{id=null, name='null', city=null, workCities=null, lifeCities=null, configFileLocation=null, company=null, context=null, contextAsText='null', beanName='null'}
 

3.2、spring 内置的实现  (主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中)

代码位置:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation(beanName, mbdToUse)

@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			//TODO mbd.isSynthetic() 表示是否合成类
			// hasInstantiationAwareBeanPostProcessors() 判断系统是否有 InstantiationAwareBeanPostProcessors
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//这个一般都是为空
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

主要实现类就一个AbstractAutoProxyCreator#postProcessBeforeInstantiation

主要作用是判断 bean是否需要被代理 ,需要被代理的类 就放入map中

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			//advisedBeans 不需要被代理的对象
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

四、Spring Bean 实例化阶段

实例化阶段主要是 根据后置处理器 推断出 实例化bean的最优构造方法,实例化对象。

第二次调用bean的后置处理器:推断实例化构造方法---》SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors

路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance(beanName, mbd, args)

接口:SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)

实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors

这个后置处理器 需要实现 SmartInstantiationAwareBeanPostProcessor接口

 

实例化方式:

   1、使用默认无参构造器:instantiateBean(beanName, mbd)

             实例化策略 - InstantiationStrategy--- instantiationStrategy = new CglibSubclassingInstantiationStrategy()---- SimpleInstantiationStrategy   

   2、使用依赖注入的构造器:autowireConstructor(beanName, mbd, ctors, args)

createBeanInstance 代码实现
//创建Bean的实例对象
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		//检查确认Bean是可实例化的
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		//使用工厂方法对Bean进行实例化
		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());
		}
        //todo 这个程序员自己提供创建对象的方法
		//  这里使用自己提供的 方法实例化对象, 不需要spring推断构造方法区实例化bean
		//  genericBeanDefinition.setInstanceSupplier(() -> new IndexService(beanFactory.getBean(OrderSevice.class)));
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		//todo 这个程序员自己提供创建对象的工厂方法 factory-method
		if (mbd.getFactoryMethodName() != null)  {
			//调用工厂方法实例化
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		//TODO 下面是重点 开始创建bean 使用容器的自动装配方法进行实例化
		//表示创建对象的构造方法没有被解析过
		boolean resolved = false;
		//是否需要自动注入
		boolean autowireNecessary = false;
		//args 一般都为空
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				//Todo 下面很重要  如果不为空 表示这个class 方法被解析过了 表示已经找到了创建对象的方式
				// 一般在原型模式中 使用 快捷方式,不需要再次解析构造方法
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				//配置了自动装配属性,使用容器的自动装配实例化
				//容器的自动装配是根据参数类型匹配Bean的构造方法
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//使用默认的无参构造方法实例化
				return instantiateBean(beanName, mbd);
			}
		}

		// Need to determine the constructor...
		//TODO 第二次调用后置处理器推断构造方法 下面是单例对象的  使用Bean的构造方法进行实例化
		//找到 class 构造方法 特殊的算法
		/* TODO spring 通过构造方法实例化 bean的原理
		      实例化这个对象---首先要推断构造方法
		  这个分两种类型
		  1、手动注入
             会在后置处理器中 找到实现 SmartInstantiationAwareBeanPostProcessor接口的类型
             AutowiredAnnotationBeanPostProcessor类中的determineCandidateConstructors 方法来推断出
             合适的构造方法创建对象
		     1.1、只有一个无参构造方法 ctors为 null 使用默认无参构造方法
		     1.2 如果有多个构造方法 ctors为 null 使用默认无参构造方法
		     1.3  如果只有一个有参构造方法 ctors不为null 因为只有一个有参数的 只能用这个了
		     1.4、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
		     1.5、多个构造方法 且多个构造方法加了@Autowired(required = true)  spring ioc容器报错
		     1.6、多个构造方法 且多个构造方法加了@Autowired(required = false)  就把构造方法都加到集合中 第二次推断
		  2、自动注入 --通过构造方法自动注入
		     2.1、如果有多个构造方法  找出最优的构造器 参数最多的 为最优的
		 */
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || //这个表示自动装配
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			//使用容器的自动装配特性,调用匹配的构造方法实例化
			//使用推断出来的构造方法找到一个可以用的 实例化bean
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		//使用默认的无参构造方法实例化
		return instantiateBean(beanName, mbd);
	}

4.1、第二次调用后置处理器推断构造方法 

接口:SmartInstantiationAwareBeanPostProcessor #determineCandidateConstructors(Class<?> beanClass, String beanName)

实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors

其中推断构造器的规则

这个分两种类型
   1、手动注入
             合适的构造方法创建对象
             1.1、只有一个无参构造方法 ctors为 null 使用默认无参构造方法
             1.2 如果有多个构造方法 ctors为 null 使用默认无参构造方法
             1.3  如果只有一个有参构造方法 ctors不为null 因为只有一个有参数的 只能用这个了
             1.4、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
             1.5、多个构造方法 且多个构造方法加了@Autowired(required = true)  spring ioc容器报错
             1.6、多个构造方法 且多个构造方法加了@Autowired(required = false)  就把构造方法都加到集合中 第二次推断

2、自动注入 --通过构造方法自动注入
             2.1、如果有多个构造方法  找出最优的构造器 参数最多的为最优的

             2.2、多个构造方法 且只有一个构造方法加了@Autowired(required = true) 用这个构造方法来创建对象
             2.3、多个构造方法 且多个构造方法加了@Autowired(required = true)  spring ioc容器报错

代码实现:

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

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				// AutowiredAnnotationBeanPostProcessor 这个后置处理 实现了 SmartInstantiationAwareBeanPostProcessor
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					//TODO 推断构造器 AutowiredAnnotationBeanPostProcessor
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

实现类:AutowiredAnnotationBeanPostProcessor #determineCandidateConstructors

//TODO 为自动依赖注入装配Bean选择合适的构造方法
	@Override
	@Nullable
	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
			throws BeanCreationException {

		// Let's check for lookup methods here..
		if (!this.lookupMethodsChecked.contains(beanName)) {
			try {
				ReflectionUtils.doWithMethods(beanClass, method -> {
					Lookup lookup = method.getAnnotation(Lookup.class);
					if (lookup != null) {
						Assert.state(beanFactory != null, "No BeanFactory available");
						LookupOverride override = new LookupOverride(method, lookup.value());
						try {
							RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
							mbd.getMethodOverrides().addOverride(override);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(beanName,
								"Cannot apply @Lookup to beans without corresponding bean definition");
						}
					}
				});
			}
			catch (IllegalStateException ex) {
				throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
			}
			this.lookupMethodsChecked.add(beanName);
		}

		//首先从容器的缓存中查找是否有指定Bean的构造方法
		// Quick check on the concurrent map first, with minimal locking.
		// candidateConstructorsCache 这个 class的构造方法的map
		Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
		if (candidateConstructors == null) {
			// Fully synchronized resolution now...
			//线程同步以确保容器中数据一致性
			synchronized (this.candidateConstructorsCache) {
				candidateConstructors = this.candidateConstructorsCache.get(beanClass);
				if (candidateConstructors == null) {
					Constructor<?>[] rawCandidates;
					try {
						//通过JDK反射机制,获取指定类的中所有声明的构造方法
						rawCandidates = beanClass.getDeclaredConstructors();
					}
					catch (Throwable ex) {
						throw new BeanCreationException(beanName,
								"Resolution of declared constructors on bean Class [" + beanClass.getName() +
								"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
					}
					//存放候选中合格的构造方法的集合
					List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
					//autowire注解中required属性指定的构造方法
					Constructor<?> requiredConstructor = null;
					//默认的构造方法
					Constructor<?> defaultConstructor = null;
					//主构造方法  把推断的主要构造方法委托给  kotlin  非kotlin的类永远为空
					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
					int nonSyntheticConstructors = 0;
					//遍历所有的构造方法,检查是否添加了autowire注解,以及是否指定了required属性
					for (Constructor<?> candidate : rawCandidates) {
						//判断是不是一个合成的类 一般不会进来
						if (!candidate.isSynthetic()) {
							nonSyntheticConstructors++;
						}
						else if (primaryConstructor != null) {
							continue;
						}
						//获取指定类中所有关于autowire的注解(Annotation)
						AnnotationAttributes ann = findAutowiredAnnotation(candidate);
						//如果指定类中没有antowire的注解
						if (ann == null) {
							Class<?> userClass = ClassUtils.getUserClass(beanClass);
							if (userClass != beanClass) {
								try {
									Constructor<?> superCtor =
											userClass.getDeclaredConstructor(candidate.getParameterTypes());
									ann = findAutowiredAnnotation(superCtor);
								}
								catch (NoSuchMethodException ex) {
									// Simply proceed, no equivalent superclass constructor found...
								}
							}
						}
						//如果指定类中有关于antowire的注解
						if (ann != null) {
							//如果antowire注解中指定了required属性
							if (requiredConstructor != null) {
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructor: " + candidate +
										". Found constructor with 'required' Autowired annotation already: " +
										requiredConstructor);
							}
							//获取autowire注解中required属性值
							boolean required = determineRequiredStatus(ann);
							//如果获取到autowire注解中required的属性值
							if (required) {
								//如果候选构造方法集合不为空
								if (!candidates.isEmpty()) {
									throw new BeanCreationException(beanName,
											"Invalid autowire-marked constructors: " + candidates +
											". Found constructor with 'required' Autowired annotation: " +
											candidate);
								}
								//当前的构造方法就是required属性所配置的构造方法
								requiredConstructor = candidate;
							}
							//将当前的构造方法添加到哦啊候选构造方法集合中
							candidates.add(candidate);
						}
						//如果autowire注解的参数列表为空
						else if (candidate.getParameterCount() == 0) {
							defaultConstructor = candidate;
						}
					}
					//如果候选构造方法集合不为空
					if (!candidates.isEmpty()) {
						// Add default constructor to list of optional constructors, as fallback.
						//如果所有的构造方法都没有配置required属性,且有默认构造方法
						if (requiredConstructor == null) {
							if (defaultConstructor != null) {
								//将默认构造方法添加到候选构造方法列表
								candidates.add(defaultConstructor);
							}
							else if (candidates.size() == 1 && logger.isWarnEnabled()) {
								logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
										"': single autowire-marked constructor flagged as optional - " +
										"this constructor is effectively required since there is no " +
										"default constructor to fall back to: " + candidates.get(0));
							}
						}
						//将候选构造方法集合转换为数组
						candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
					}
					//TODO 这里是判断构造方法 是否只有一个有参构造 如果一个有参构造则 为有效的构造方法
					else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
						candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
					}
					//下面两个都不成立 primaryConstructor != null
					else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
					}
					else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor};
					}
					else {
						//如果候选构造方法集合为空,则创建一个空的数组
						candidateConstructors = new Constructor<?>[0];
					}
					//将类的候选构造方法集合存放到容器的缓存中
					this.candidateConstructorsCache.put(beanClass, candidateConstructors);
				}
			}
		}
		//返回指定类的候选构造方法数组,如果没有返回null
		return (candidateConstructors.length > 0 ? candidateConstructors : null);
	}

4.2、instantiateBean(beanName, mbd)使用默认无参构造器实例化对象

当推断出来使用默认无参构造 

//使用默认的无参构造方法实例化Bean对象
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			//获取系统的安全管理接口,JDK标准的安全管理API
			if (System.getSecurityManager() != null) {
				//这里是一个匿名内置类,根据实例化策略创建实例对象
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				//将实例化的对象封装起来
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

4.3、使用依赖注入的构造器实例化对象:autowireConstructor(beanName, mbd, ctors, args)

使用条件:推断处理的 构造器方法不为null或者开启自动装配或者 使用指定入参的构造方法

if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || //这个表示自动装配
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			//使用容器的自动装配特性,调用匹配的构造方法实例化
			//使用推断出来的构造方法找到一个可以用的 实例化bean
			return autowireConstructor(beanName, mbd, ctors, args);
		}

具有实现:ConstructorResolver#autowireConstructor 这里会再次推断构造方法实例化对象。

 

public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);
        //TODO 最后被确认使用的 构造方法
		Constructor<?> constructorToUse = null;
		//这里面存放的 构造方法的参数
		ArgumentsHolder argsHolderToUse = null;
		//最终确定的参数
		Object[] argsToUse = null;

		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			Object[] argsToResolve = null;
			synchronized (mbd.constructorArgumentLock) {
				//判断当前类 有没有解析构造方法 单例一般都为false
				constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
				//原型模式会走这个
				if (constructorToUse != null && mbd.constructorArgumentsResolved) {
					// Found a cached constructor...
					argsToUse = mbd.resolvedConstructorArguments;
					if (argsToUse == null) {
						argsToResolve = mbd.preparedConstructorArguments;
					}
				}
			}
			//转化 参数的属性值
			if (argsToResolve != null) {
				argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
			}
		}
        //这个单例模式的处理
		if (constructorToUse == null) {
			// Need to resolve the constructor.
			//判断是否需要自动注入
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;
            //构造方法参数个数的最小值
			int minNrOfArgs;
			//这个数根据传入参数做判断
			if (explicitArgs != null) {
				//表示实例spring 那个构造方法最少要多少
				minNrOfArgs = explicitArgs.length;
			}
			else {
				//获取构造方法的 参数
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				//
				resolvedValues = new ConstructorArgumentValues();
				//得到构造方法参数个数的最小值
				//todo 这个一般为0 除非在实例化的时候
				/*
				   GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("indexService");
                   genericBeanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanFactory.getBean(UserServiceTest.class));
				 */
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}

			// Take specified constructors, if any.
			//TODO 开始处理构造方法
			Constructor<?>[] candidates = chosenCtors;
			if (candidates == null) {
				Class<?> beanClass = mbd.getBeanClass();
				try {
					//拿到索引构造方法再次推断
					candidates = (mbd.isNonPublicAccessAllowed() ?
							beanClass.getDeclaredConstructors() : beanClass.getConstructors());
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
				}
			}
			//todo 对构造方法进行排序
			// 排序规则 1、public 2、参数个数
			AutowireUtils.sortConstructors(candidates);
			//差异值
			int minTypeDiffWeight = Integer.MAX_VALUE;
			//模糊不清的构造方法
			Set<Constructor<?>> ambiguousConstructors = null;
			LinkedList<UnsatisfiedDependencyException> causes = null;

			for (Constructor<?> candidate : candidates) {
				Class<?>[] paramTypes = candidate.getParameterTypes();
                 // TODO 最终使用的 如果找到一个就直接退出了 最重要的条件  argsToUse.length > paramTypes.length
				if (constructorToUse != null && argsToUse.length > paramTypes.length) {
					// Already found greedy constructor that can be satisfied ->
					// do not look any further, there are only less greedy constructors left.
					break;
				}
				if (paramTypes.length < minNrOfArgs) {
					continue;
				}
                //最后要使用的参数
				ArgumentsHolder argsHolder;
				if (resolvedValues != null) {
					//得到当前构造方法的参数名字
					try {
						String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
						if (paramNames == null) {
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								paramNames = pnd.getParameterNames(candidate);
							}
						}
						//TODO
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
								getUserDeclaredConstructor(candidate), autowiring);
					}
					catch (UnsatisfiedDependencyException ex) {
						if (this.beanFactory.logger.isTraceEnabled()) {
							this.beanFactory.logger.trace(
									"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
						}
						// Swallow and try next constructor.
						if (causes == null) {
							causes = new LinkedList<>();
						}
						causes.add(ex);
						continue;
					}
				}
				else {
					// Explicit arguments given -> arguments length must match exactly.
					if (paramTypes.length != explicitArgs.length) {
						continue;
					}
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				//计算差异值 -1024
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				// Choose this constructor if it represents the closest match.
				if (typeDiffWeight < minTypeDiffWeight) {
					constructorToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					minTypeDiffWeight = typeDiffWeight;
					ambiguousConstructors = null;
				}
				//模糊不清楚的 两个构造方法算法一样 会随机选择一个
				else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
					if (ambiguousConstructors == null) {
						ambiguousConstructors = new LinkedHashSet<>();
						ambiguousConstructors.add(constructorToUse);
					}
					//模糊不清楚的
					ambiguousConstructors.add(candidate);
				}
			}
            //如果没有找到处理异常
			if (constructorToUse == null) {
				if (causes != null) {
					UnsatisfiedDependencyException ex = causes.removeLast();
					for (Exception cause : causes) {
						this.beanFactory.onSuppressedException(cause);
					}
					throw ex;
				}
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Could not resolve matching constructor " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
			}
			//mbd.isLenientConstructorResolution() 宽松模式
			else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Ambiguous constructor matches found in bean '" + beanName + "' " +
						"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
						ambiguousConstructors);
			}

			if (explicitArgs == null) {
				//todo
				argsHolderToUse.storeCache(mbd, constructorToUse);
			}
		}

		try {
			final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
			Object beanInstance;

			if (System.getSecurityManager() != null) {
				final Constructor<?> ctorToUse = constructorToUse;
				final Object[] argumentsToUse = argsToUse;
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
						beanFactory.getAccessControlContext());
			}
			else {
				beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
			}

			bw.setBeanInstance(beanInstance);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean instantiation via constructor failed", ex);
		}
	}

五、处理合并BeanDefinition与解决循环依赖后置处理器

实例化后会第三和第四调用后置处理器

5.1、第三调用后置处理器MergedBeanDefinitionPostProcessor

这里主要解决 处理合并BeanDefinition的问题

入口:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)

接口:这个后置处理器 需要实现 MergedBeanDefinitionPostProcessor 接口中的postProcessMergedBeanDefinition方法

1、合并相关介绍:

为什么会提前合并 下面代码

通过类型找到名字---返回一个BeanFactoryPostProcessor的集合--完成了合并

不能用原始的BeanDefinition 去比较 必须合并

代码流程 ---AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory);-->>PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());-->DefaultListableBeanFactory.getBeanNamesForType(@Nullable Class<?> type) -->RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

/通过类型找到名字---返回一个BeanFactoryPostProcessor的集合--完成了合并
//返回一个BeanDefinition 后置工厂的名字的集合--通过名字实例化BeanFactoryPostProcessor
String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }

但是在实例化bean的时候会重新在去 合并bd 会把缓存中的合并后的BeanDefinition删除在重新合并

AbstractAutowireCapableBeanFactory applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);调用后置处理的源码

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

1.1 、实现类:AutowiredAnnotationBeanPostProcessor

  • findAutowiredMetadata----找出所有需要完成注入的“点”-----@Autowired @Value注解方法或者属性---为什么不需要构造方法
  • ​​​​checkConfigMembers----injectedElements 做了一个复制
@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		//
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

1.2、实现类:CommonAnnotationBeanPostProcessor

  • 调用父类的方法,查找所有的生命周期回调方法---初始化和销毁
  • findResourceMetadata----找出所有需要完成注入的“点”-----@Resource注解
  • checkConfigMembers----injectedElements 做了一个复制
@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

两者使用的bean的后置处理器不一样的。

5.2、第四次调用后置处理器 解决循环依赖提前暴露一个工厂

这个工厂是一个lambda表达式,在出现循环依赖的时候执行

重点 解决循环依赖 提前暴露的是一个工厂 而不是一个对象;

地址:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference(beanName, mbd, bean)

//向容器中缓存单例模式的Bean对象,以防循环引用
		//TODO 判断是否允许循环依赖
		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");
			}
			//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
			//TODO 第四调用后置处理器
			// 重点 解决循环依赖 提前暴露的是一个工厂 而不是一个对象
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

接口: SmartInstantiationAwareBeanPostProcessor# getEarlyBeanReference

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;
	}

实现类:AbstractAutoProxyCreator #getEarlyBeanReference

下面是添加到二级缓存中

@Override
	public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
			this.earlyProxyReferences.add(cacheKey);
		}
		return wrapIfNecessary(bean, beanName, cacheKey);
	}

六、spring bean实例化后置阶段

这个阶段主要判断当前实例化的bean是否需要属性注入

6.1、第五次调用后置处理器 :属性是否注入InstantiationAwareBeanPostProcessor

路径:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(beanName, mbd, instanceWrapper)

//todo 第五次---属性是否注入InstantiationAwareBeanPostProcessor
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

接口:InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)

所有spring内置的实现类都为true

6.2、测试实例 

我们当创建use bean的时候放回 false。这样这个bean就不会填充任何属性了。

/**
 * Bean 实例化生命周期示例
 *
 * @Author: dukun0210
 * @Date: 2021/2/17 19:23
 */
public class BeanInstantiationDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 方法一:添加 BeanPostProcessor 实现 MyInstantiationAwareBeanPostProcessor
        beanFactory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessorDome());
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        String location = "META-INF/dependency-lookup-context.xml";
        Resource resource = new ClassPathResource(location);
        // 指定字符编码 UTF-8
        EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
        beanDefinitionReader.loadBeanDefinitions(encodedResource);
        // 通过 Bean Id 和类型进行依赖查找
        User user = beanFactory.getBean("user", User.class);
        System.out.println(user);
        User superUser = beanFactory.getBean("superUser", User.class);
        System.out.println(superUser);

    }

    /**
     * 实现 后置处理器
     */
    static class  MyInstantiationAwareBeanPostProcessorDome implements InstantiationAwareBeanPostProcessor {

        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass)){
                //把配置完成的 superUser bean覆盖
                return  new SuperUser();
            }
            return null;//这里表示什么都不变化
        }
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass)){
                //如果是 user 对象不允许属性的赋值
                return  false;
            }
            return true;//这里表示什么都不变化
        }
    }
}

总结:

 

 

 

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值