🤡 IoC & DI

吞佛童子2022年6月20日
  • frame
  • Spring
大约 16 分钟

🤡 IoC & DI

  1. IoC
    • 由 Spring 容器控制对象的生命周期 & 对象间的关系
    • 当我们需要某个对象时,需要从 BeanFactory & ApplicationContext 容器 中获取
    • 优点是:解耦
  2. DI
    • 容器在实例化对象时,将它依赖的类注入给它
  3. 为什么要有 IoC & DI?
    • 实现 解耦
    • 硬编码会造成对象间的过度耦合,使用 IoC 后,我们可以不用关心对象间的依赖,专心开发业务

基于 SpringBoot 2.x

1. ManageApplication 启动类

package com.manage;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ManageApplication {

    public static void main(String[] args) {
        SpringApplication.run(ManageApplication.class, args);
    }

}

2. SpringApplication.run(args)

public class SpringApplication {
    // ...
    // 属性
    private Set<Class<?>> primarySources;
    private Set<String> sources;
    private Class<?> mainApplicationClass;
    private Mode bannerMode;
    private boolean logStartupInfo;
    private boolean addCommandLineProperties;
    private boolean addConversionService;
    private Banner banner;
    private ResourceLoader resourceLoader;
    private BeanNameGenerator beanNameGenerator;
    private ConfigurableEnvironment environment;
    private WebApplicationType webApplicationType;
    private boolean headless;
    private boolean registerShutdownHook;
    private List<ApplicationContextInitializer<?>> initializers;
    private List<ApplicationListener<?>> listeners;
    private Map<String, Object> defaultProperties;
    private List<BootstrapRegistryInitializer> bootstrapRegistryInitializers;
    private Set<String> additionalProfiles;
    private boolean allowBeanDefinitionOverriding;
    private boolean isCustomEnvironment;
    private boolean lazyInitialization;
    private String environmentPrefix;
    private ApplicationContextFactory applicationContextFactory;
    private ApplicationStartup applicationStartup;

    // 构造函数
    public SpringApplication(Class<?>... primarySources) {
        this((ResourceLoader)null, primarySources);
    }
    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        // 属性赋初值
        this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;
        this.registerShutdownHook = true;
        this.additionalProfiles = Collections.emptySet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
        this.applicationStartup = ApplicationStartup.DEFAULT;
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
        // 1) 判断应用程序类型,分为 Servlet, Reactive, None 三种枚举类型
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        // 2) 从 SpringFactories 加载 初始化器
        this.bootstrapRegistryInitializers = this.getBootstrapRegistryInitializersFromSpringFactories();
        // 3) 设置 应用上下文初始化器
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
        // 4) 设置 应用上下文监听器
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        // 5) 找到 main 方法,设置为 运行的主类
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }
    
    // run() 方法
    public ConfigurableApplicationContext run(String... args) {
        // 1. 启动计时器
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 2. 系统属性设置
        DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
        ConfigurableApplicationContext context = null;
        this.configureHeadlessProperty();
        // 3. 初始化监视器并启动,发布 ApplicationStartedEvent 事件
        // 1) 获取所有 监视器
        SpringApplicationRunListeners listeners = this.getRunListeners(args); 
        // 2) starting 函数 - 执行 multicastEvent 方法,唤醒所有的 事件监听器
        //    multicastEvent 方法 会执行 invokeListener 方法
        //    会执行 invokeListener 方法 会 调用 listener.onApplicationEvent(event),只要事件监听器重写了该方法,那么就会执行 具体事件
        listeners.starting(bootstrapContext, this.mainApplicationClass); 

        try {
            // 4. 环境配置,发布 ApplicationEnvironmentPreparedEvent 事件
            // 在这一步中,会触发相关监视器 ConfigFileApplicationListener,加载 properties & yml 文件
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            // 5. 打印 banner
            Banner printedBanner = this.printBanner(environment);
            // 6. 创建 ApplicationContext
            context = this.createApplicationContext();
            context.setApplicationStartup(this.applicationStartup);
            // 7. 上下文 前置处理,装配 Context 的环境变量等
            this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
            // 8. 刷新 上下文 - 继续进入
            this.refreshContext(context);
            // 9. 上下文刷新的后置处理
            this.afterRefresh(context, applicationArguments);
            // 10. 计时器 结束
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }
            // 11. 将 上下文 事件 发布 AvailabilityChangeEvent.publish(context, LivenessState.CORRECT)
            listeners.started(context);
            // 12. 执行 runner 运行器运行
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            // 13. 事件发布 AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC)
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }
}

3. refreshContext(context)

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
    // ......
	@Override
	public void refresh() throws BeansException, IllegalStateException {
	    // 加锁,保证线程安全
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// 1.准备工作
            // 记录下容器的启动时间、
            // 标记“已启动”状态,关闭状态为false、
            // 加载当前系统属性到环境对象中
            // 准备一系列监听器以及事件集合对象
			prepareRefresh();

			// 2. 创建容器对象:DefaultListableBeanFactory,加载 XML 配置文件的属性到当前的工厂中(默认用命名空间来解析),
			// 就是上面说的BeanDefinition(bean的定义信息)这里还没有初始化,只是配置信息都提取出来了,(包含里面的value值其实都只是占位符)
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3. BeanFactory的准备工作,设置BeanFactory的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的bean等
			prepareBeanFactory(beanFactory);

			try {
				// 4. 若 bean 实现了该方法,那么在 bean 被加载、注册,初始化之前,会被调用该方法,进行一些自定义操作
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// 5. 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
				// 在这一步中,会将 @Value 注解需要的属性值从 properties 文件获取进行赋值
				invokeBeanFactoryPostProcessors(beanFactory);

				// 6. 注册 BeanPostProcessor  处理器 这里只是注册功能,真正的调用的是getBean方法
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// 7.初始化当前 ApplicationContext 的 MessageSource,即国际化处理
				initMessageSource();

				// 8.初始化当前 ApplicationContext 的事件广播器,
				initApplicationEventMulticaster();

				// 9. 钩子方法,重写该方法以在这里初始化一些特殊的 Bean(发生在在初始化 singleton beans 之前)
				onRefresh();

				// 10. 注册事件监听器,监听器需要实现 ApplicationListener 接口
				registerListeners();

				// 11. 初始化所有的 不允许懒加载的 剩余的 singleton beans - 
				finishBeanFactoryInitialization(beanFactory);

				// 12. 广播事件,ApplicationContext 初始化完成
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

    // 初始化剩余的 singleton beans
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

		// 实例化所有剩余的 & 不是懒加载的单例 bean - 继续跟入
		beanFactory.preInstantiateSingletons();
	}

4. preInstantiateSingletons()

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { 
	// .......	
	@Override
    public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Pre-instantiating singletons in " + this);
        }

        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        while(true) {
            String beanName;
            Object bean;
            do {
                while(true) {
                    RootBeanDefinition bd;
                    do {
                        do {
                            do {
                                if (!var2.hasNext()) { // 不存在后续节点
                                    var2 = beanNames.iterator();

                                    while(var2.hasNext()) {
                                        beanName = (String)var2.next();
                                        Object singletonInstance = this.getSingleton(beanName);
                                        if (singletonInstance instanceof SmartInitializingSingleton) {
                                            StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
                                            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                            if (System.getSecurityManager() != null) {
                                                AccessController.doPrivileged(() -> {
                                                    smartSingleton.afterSingletonsInstantiated();
                                                    return null;
                                                }, this.getAccessControlContext());
                                            } else {
                                                smartSingleton.afterSingletonsInstantiated();
                                            }

                                            smartInitialize.end();
                                        }
                                    }

                                    return;
                                }

                                // 存在下一个节点
                                beanName = (String)var2.next();
                                // 合并父 Bean 中的配置,例如 <bean id="" class="" parent="" /> 中的 parent
                                bd = this.getMergedLocalBeanDefinition(beanName);
                            } while(bd.isAbstract()); // 非抽象
                        } while(!bd.isSingleton()); // 单例
                    } while(bd.isLazyInit()); // 非懒加载 - isLazyInit 是 bd 类的一个 boolean 属性

                    // 通过 FactoryBean 实现的复杂 bean,在 beanName 前面加上 ‘&’ 符号。再调用 getBean
                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }

                    // 对于普通的 Bean,只要调用 getBean(beanName) - 继续跟入
                    this.getBean(beanName);
                }
            } while(!(bean instanceof FactoryBean));

            FactoryBean<?> factory = (FactoryBean)bean;
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                SmartFactoryBean var10000 = (SmartFactoryBean)factory;
                ((SmartFactoryBean)factory).getClass();
                isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
            } else {
                isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
            }

            if (isEagerInit) {
                this.getBean(beanName);
            }
        }
    }

5. getBean(String name)

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { 
    // ......
	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}


	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * @param name 要获取的 bean 的名称
	 * @param requiredType 要获取的 bean 指定的所属类型
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @param typeCheckOnly 拥有的实例是否有类型检查
	 * @return an instance of the bean
	 * @throws BeansException if the bean could not be created
	 */
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			String name, 
			@Nullable Class<T> requiredType, 
			@Nullable Object[] args, 
			boolean typeCheckOnly) throws BeansException {

		// 将传入的 bean 名称进行一些转换,如果有特殊的名称,例如 FactoryBean(前面带 ‘&’) 等
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// 判断该 bean 是否已经创建过 - 三级缓存模型获取 单例bean
		Object sharedInstance = getSingleton(beanName);
		// 已经创建过,则返回
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			// 如果是 FactoryBean ,返回 factory.getObject() 方法生成的 类对象; 普通 Bean ,直接返回 sharedInstance
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 没有创建过该 bean
			// 若该 bean 已经创建了 Prototype 类型,抛异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 检查一下这个 BeanDefinition 在容器中是否存在
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				} else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				} else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				} else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 初始化 该 bean 依赖的所有 bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
					    // 依赖的 bean 之间不允许出现循环依赖问题
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep); // 初始化依赖项
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// 如果是 singleton scope 的,创建 singleton 的实例
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					// 该方法如果发现是 FactoryBean,则会调用 FactoryBean.getObject() 方法得到 bean
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				// 如果是 prototype scope 的,创建 prototype 的实例
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				// // 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
				beanCreation.end();
			}
		}

		return adaptBeanInstance(name, beanInstance, requiredType);
	}
}

6. createBean & doCreateBean

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {

		// 日志打印
		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 判断方法是否被重写过
		try {
			mbdToUse.prepareMethodOverrides();
		} catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(
			        mbdToUse.getResourceDescription(),
					beanName, 
					"Validation of method overrides failed", 
					ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			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 {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args); // 创建 bean,继续进入
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		} catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

	/**
	 * 主要包含以下步骤:
	 * 1. 实例化,创建 bean 实例
	 *    1.1 实例化完成后,如果满足 提前暴露 条件,需要将该 bean 放入 三级缓存
	 * 2. 填充属性
	 * 3. bean 初始化
	 */
	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {

		// 1. 实例化 bean
		BeanWrapper instanceWrapper = null;
		// 如果是单例模式,从 factoryBeanInstanceCache 缓存中获取 BeanWrapper 实例对象并删除缓存
		if (mbd.isSingleton()) {
		    // 如果是 factoryBean,这里 instanceWrapper 会被赋值 != null
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); 
		}
		// 非 factoryBean,实例化 bean
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args); 
		}
		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) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// 将该 bean 放入 三级缓存
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 属性填充 & 初始化 bean
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper); // 填充属性
			exposedObject = initializeBean(beanName, exposedObject, mbd); // 初始化 bean 实例对象
		} 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 " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// 注册 bean 的销毁方法
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}
	
	// 属性填充 - 依赖注入
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
       //1. 校验实例
       if (bw == null) {
           if (mbd.hasPropertyValues()) {
               throw new BeanCreationException(
                       mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
           }
           else {
               // Skip property population phase for null instance.
               return;
           }
       }
       /*
        * 2. 在设置属性之前给 InstantiationAwareBeanPostProcessors 最后一次改变 bean 的机会。
        * 关于这段后置引用,官方的解释是:让用户可以自定义属性注入。比如用户实现一
        * 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
        * postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。当然,如果无
        * 特殊需求,直接使用配置中的信息注入即可。另外,Spring 并不建议大家直接实现
        * InstantiationAwareBeanPostProcessor 接口,如果想实现这种类型的后置处理器,更建议
        * 通过继承 InstantiationAwareBeanPostProcessorAdapter 抽象类实现自定义后置处理器。
        */
       boolean continueWithPropertyPopulation = true;
   
       // bean 不是"合成"的,即未由应用程序本身定义 && 持有 InstantiationAwareBeanPostProcessor
       if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
           // 遍历所有的 BeanPostProcessors
           for (BeanPostProcessor bp : getBeanPostProcessors()) {
               if (bp instanceof InstantiationAwareBeanPostProcessor) {
                   InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                   // 返回值为是否继续填充 bean
                   // postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
                   // 一般情况下,应该是返回true 。
                   // 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实例。
                   if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                       continueWithPropertyPopulation = false;
                       break;
                   }
               }
           }
       }
       // 如果后置处理器发出停止填充命令,则终止后续操作
       if (!continueWithPropertyPopulation) {
           return;
       }
       
       // 3. 获取Bean的属性值
       PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

       // 3.1 xml方式    即xml中<beans>节点中的 default-autowire 属性
       if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
               mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
               
           // 将 PropertyValues 封装成 MutablePropertyValues 对象
           // MutablePropertyValues 允许对属性进行简单的操作,并提供构造函数以支持Map的深度复制和构造。
           MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
           
           //根据 Bean 名称 进行 自动装配
           if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
               autowireByName(beanName, mbd, bw, newPvs);
           }

           //根据 Bean类型 进行 自动装配
           if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
               autowireByType(beanName, mbd, bw, newPvs);
           }
           pvs = newPvs;
       }
       
       // 是否已经注册了 InstantiationAwareBeanPostProcessors
       boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
       
       //是否需要依赖检查(xml)
       boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);   
       
       // 3.2 注解方式
       if (hasInstAwareBpps || needsDepCheck) { // 已经注册 InstantiationAwareBeanPostProcessors || 需要依赖检查
           if (pvs == null) {
               pvs = mbd.getPropertyValues();
           }
           PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
           if (hasInstAwareBpps) {
               for (BeanPostProcessor bp : getBeanPostProcessors()) {
                   if (bp instanceof InstantiationAwareBeanPostProcessor) {
                       InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                       // 具体处理属性注入(注解方式)- 例,@Value()、@Resource、@Autowire
                       pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                       if (pvs == null) {
                           return;
                       }
                   }
               }
           }
           //依赖检查 (xml)
    	   if (needsDepCheck) {
               checkDependencies(beanName, mbd, filteredPds, pvs);
           }
       }
    	if (pvs != null) {
           //对属性进行注入 (xml)
           applyPropertyValues(beanName, mbd, bw, pvs);
       }
	}
	
	//
	// 初始化 bean -- 见下
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
      // ....
    }
}

7. initializeBean()


补充

1) BeanFactory

① 类图

img.png

  1. ListableBeanFactory:可以获取多个 Bean
  2. HierarchicalBeanFactory:可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系
  3. BeanFactory:获取单个 Bean
  4. AutowireCapableBeanFactory:自动装配 Bean,ApplicationContext 虽没有继承它,但通过 getAutowireCapableBeanFactory() 组合了它
  5. ConfigurableBeanFactory:单例bean的注册以及生成实例,统计单例bean等信息
  6. ConfigurableListableBeanFactory:增加了一些其他功能:类加载器、类型转化、属性编辑器、BeanPostProcessor、bean定义、处理bean依赖关系、 bean如何销毁等等一些还有其他的功能
  7. DefaultListableBeanFactory:实现 BeanFactory 所有功能同时也能注册 BeanDefinition

② 补充

  • BeanFactory 采用 延迟加载 方式,只有使用 Bean 时才会进行实例化
  • Spring 为 BeanFactory 提供了多种实现,常见的有 XmlBeanDefinitionReader & DefaultListableBeanFactory
  • 常见方法有 getBean(String name) & createBean()

2) FactoryBean

  1. 一般情况下,Spring 通过 反射 实现 bean 的实例化,当过程比较复杂时,需要提供大量配置信息,此时就可采用 FactoryBean 的方式,通过 编码 方式得到 bean
  2. 一种特殊的 bean,为工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑,常用于完成复杂的 bean 的创建工作
  3. preInstantiateSingletons() 中,如果发现为 isFactoryBean(beanName),那么在 beanName 前面加上 ‘&’ 符号,再调用 getBean
  4. 在调用 getBean 时,如果发现为 FactoryBean 对象,那么会调用 FactoryBean.getObject() 方法返回 bean
  5. 可以用来创建比较复杂的 bean | 第三方 bean 难以修改的情形
public interface FactoryBean<T> {
	@Nullable
	T getObject() throws Exception;
	
	@Nullable
	Class<?> getObjectType();
	
	default boolean isSingleton() {
		return true; // 默认为单例,支持 单例 & prototype
	}
}

3) ApplicationContext

  1. 继承了 BeanFactory,实现了其功能
  2. 扩展了其他功能,例如国际化访问、事件传播等
  3. 一次性创建所有 Bean 实例,占用内存空间,启动较慢

4) ObjectFactory

  1. 用于 延迟查找,只有在执行 getObject() 时才会 实例化 bean
@FunctionalInterface
public interface ObjectFactory<T> {

	/**
	 * 返回一个 新实例对象
	 */
	T getObject() throws BeansException;

}
上次编辑于: 2022/10/10 下午8:43:48
贡献者: liuxianzhishou