Spring---IOC容器

前段时间看到面试题问到Spring bean的生命周期,一脸黑线。拒绝做api调用工程师可能就得从这些底层的原理开始。离开实习了一年的公司就是为了有机会去大厂接触更深层次的技术,提升自己价值。MMP结果应届毕业生的我不能参加校招,投简历动不动都是3-5年,5-10年。对不起弟弟我们不要一年的。。。。心痛。今日吐槽就到这里。

准备

研究spring源码前你可能先需要到github上拉一份spring源码自己跑起来,有问题找度娘,自己去拉取配置一下。
在这里插入图片描述

开始:

IOC 总体来说有两处地方最重要,一个是创建 Bean 容器,一个是初始化 Bean,下面我也尽我所能把自己学到的都写出来。按道理说从XML配置角度分析更适合,但是介于实际工作中我们基本已经不使用这种方式,我还是从注解方面分析。其实举一反三明白其中一个再去看另外一个会容易很多。

先看下最基本的启动 Spring 容器的例子:

注解

AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class);// AppConfig用@ComponentScan配置一个扫描路劲用于测试
System.out.println(annotationConfigApplicationContext.getBean(xxx.class));// 这样就能从IOC容器中拿到我们已经注册的Bean也是源码分析的入口 

XML

 ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationfile.xml");

不管是AnnotationConfigApplicationContext还是ClassPathXmlApplicationContext,从名字上就可以猜出一二,就是根据配置类和在 ClassPath 中寻找 xml 配置文件,根据配置类或者 xml 文件内容来构建 ApplicationContext也可以理解为初始化spring环境。当然,构建 ApplicationContext 的方案有很多,我们先来看看大体的继承结构是怎么样的:
在这里插入图片描述
AnnotationConfigApplicationContext 是基于注解来使用的,它不需要配置文件,采用 java 配置类和各种注解来配置,是比较简单的方式,也是大势所趋。下面源码分析我们就采用注解方式研究。

BeanFactory继承图:

在这里插入图片描述
对这两个关系图有一个印象后我们正式进入源码分析:

启动过程分析

下面将会是冗长的代码分析,一定要打开自己的源码
第一步,我们肯定要从AnnotationConfigApplicationContex的构造方法说起。看看里面都做了什么

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this(); // 在调用自己的构造方法前先会调用父类的构造方法
		register(annotatedClasses);      
		refresh() // 核心方法下面着重分析
	}

因为AnnotationConfigApplicationContext extends GenericApplicationContext所以我们去看一下它父类的构造方法:

  /**
	 * 创建一个工厂,也即我们常说的bean工厂
	 * 后面提到的obtainFreshBeanFactory()方法将会对其初始化
	 */
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

我们可以看到在GenericApplicationContext这里首先初始化了一个Bean工厂,所以我们常说的Bean工厂就是 DefaultListableBeanFactory

再看一下this(); 调用的无参构造方法做了什么

public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		// 可以用来扫描包或者类,继而转换成bd,但实际上我们扫描包的工作不是scanner这个对象来完成,
		// 是spring自己new的一个ClassPathBeanDefinitionScanner
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

在这里初始化了注解模式下的bean自定义读取器,和classpath类型的bean自定义扫描器。BD是什么?beanDefinition对象,就像java中的Class类用来描述类的类,spring中的beanDefinition是用来描述我们的bean对象的。当spring将类扫描到后就会把类中各种信息拿出来,然后new一个对应的beanDefinition对象(spring中的类是根据BD产生的而不是Class),将扫描到的类信息放入到这个BD对象里然后放入到DefaultListableBeanFactory中定义的 beanDefinitionMap中。后面大家就会对这个概念有更深入的理register(annotatedClasses); 不是当前的重点稍微解释下,它调用了AnnotationConfigApplicationContext 构造函数初始化的this.reader.register(annotatedClasses); 注册配置类,将启动类变为beanDefinition对象放入map中。这里先不用关心可以直接跳过,我感觉自己理解的还不够深免得说错误导大家。

下面才是我们的重中之重:

refresh() 方法: 这是我们spring中最重要的方法没有之一,因为我们整个bean的生命周期都围绕个方法。下面是我自己学习时候打的注释方便阅读理解,从学习java第一天起就认识到开源这个词,能把有用的东西分享给别人总是很好的。(注释地方可能有不是很准确的地方,如果有人发现希望纠正一下)

@Override
	public void refresh() throws BeansException, IllegalStateException {
		// 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			// 准备工作(刷新上下文环境),记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
			// 初始化属性源(property source)配置
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 注意,这个方法是全文最重要的部分之一,这里将会初始化 BeanFactory、加载 Bean、注册 Bean 等等。
			// 当然,这步结束后,org.springframework.context.annotation.Bean 并没有完成初始化。这里指的是 Bean 实例并未在这一步生成。
			// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
			// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
			// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
			// 返回一个工厂,之后对其初始化
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// return getBeanFactory();

			// Prepare the bean factory for use in this context.
			// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean(7)
			//准备工厂
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
				// 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
				// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
				// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
				// 当前没有任何代码,可能准备再后面版本进行扩展
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
				// beanFactory后置处理器,调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
				// 在spring的环境中去执行已经被注册的factory Processors
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
				// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
				// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 从方法名就可以知道,典型的模板方法(钩子方法),
				// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
				onRefresh();

				// Check for listener beans and register them.
				// 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.实例化所有的不是懒加载的实例对象
				// 创建单例对象,重点,重点,重点
				// 初始化所有的 singleton beans
				//(lazy-init 的除外)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 最后,广播事件,ApplicationContext 初始化完成
				finishRefresh();
			}

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

				// Destroy already created singletons to avoid dangling resources.
				// 销毁已经初始化的 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();
			}
		}
	}

这里简单说下为什么是 refresh(),而不是 init() 这种名字的方法。因为 ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建的,refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。往下看,refresh() 方法里面调用了那么多方法,就知道肯定不简单了,先看个大概,细节之后会详细说。

在这之前我们需要先了解一个很关键的接口 BeanFactoryPostProcessor
spring在初始化时其实是允许程序员干预这个过程的,它本身提供了很多拓展点,Bean Factory Post Processor就是其中一个。后面还会有提到

void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

postProcessBeanFactory连beanFactory都给我们了,也代表着我们可以主动的去更改BD创建的过程,比如我想把一个XXXBean的scop设置为singleton。

public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		GenericBeanDefinition test2 = (GenericBeanDefinition) beanFactory.getBeanDefinition("test2");
		test2.setScope("singleton");
	}
}

对这个接口有了一定理解后我们正式进入 refresh() 方法:

我们Bean的实例化真正发生在finishBeanFactoryInitialization(beanFactory) ;方法中,上面代码注释已经对其他方法功能有了一个初步的介绍。但是我们还是从头来简单看一下。

1.创建 Bean 容器前的准备工作

prepareRefresh();
准备工作(刷新上下文环境),记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
初始化属性源(property source)配置

protected void prepareRefresh() {
		// Switch to active.
		// 记录启动时间,
		// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		initPropertySources();// For subclasses: do nothing by default.
		
		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		// 校验 xml 配置文件
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

2.创建 Bean 容器,加载并注册 Bean

obtainFreshBeanFactory()。注意,这个方法是全文最重要的部分之一,这里将会初始化 BeanFactory、加载 Bean、注册 Bean 等等。这步完成后,XML配置文件和基于注解的Bean就会解析成一个个 BD,注册到 BeanFactory 中,当然,这步结束后,Bean 并没有完成初始化。这里指的是 Bean 实例并未在这一步生成。

创建 Bean 容器:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等
		// 如果 ApplicationContext 中已经加载过 BeanFactory 了,销毁所有 Bean,关闭 BeanFactory
		// 注意,应用中 BeanFactory 本来就是可以多个的,这里可不是说应用全局是否有 BeanFactory,而是当前
		/**
		 *{@link AbstractRefreshableApplicationContext#refreshBeanFactory()}
		 */
		refreshBeanFactory();
		// 返回刚刚创建的 BeanFactory
		return getBeanFactory();
	}

refreshBeanFactory();

// BeanDefinition 的覆盖问题可能会有开发者碰到这个坑,就是在配置文件中定义 bean 时使用了相同的 id 或 name,
	// 默认情况下,allowBeanDefinitionOverriding 属性为 null,如果在同一配置文件中重复了,会抛错,但是如果不是同一配置文件中,会发生覆盖。
	//循环引用也很好理解:A 依赖 B,而 B 依赖 A。或 A 依赖 B,B 依赖 C,而 C 依赖 A。
	//默认情况下,javax.swing.Spring 允许循环依赖,当然如果你在 A 的构造方法中依赖 B,在 B 的构造方法中依赖 A 是不行的。
	
	@Override
	protected final void refreshBeanFactory() throws BeansException {
		// 如果 ApplicationContext 中已经加载过 BeanFactory 了,销毁所有 Bean,关闭 BeanFactory
		// 注意,应用中 BeanFactory 本来就是可以多个的,这里可不是说应用全局是否有 BeanFactory,而是当前
		// ApplicationContext 是否有 BeanFactory
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			// 初始化一个 DefaultListableBeanFactory,为什么用这个,我们马上说。
			// ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory,而且实
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			// 用于 BeanFactory 的序列化,我想不部分人应该都用不到
			beanFactory.setSerializationId(getId());
			// 下面这两个方法很重要,别跟丢了,具体细节之后说
			// 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
			// 在后面getBean方法中会这几道spring如何解决循环依赖问题
			customizeBeanFactory(beanFactory);
			// 加载 Bean 到 BeanFactory 中
			/** {@link AbstractXmlApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory)}*/
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

为了方便查阅再贴一遍
看到这里的时候,就应该站在高处看 ApplicationContext 了,ApplicationContext 继承自 BeanFactory,但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)。以后所有的 BeanFactory 相关的操作其实是委托给这个实例来处理的。
在这里插入图片描述
我们可以看到 ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory,而且实现类 DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路。所以结论就是,最底下这个家伙 DefaultListableBeanFactory 基本上是最牛的 BeanFactory 了,这也是为什么这边会使用这个类来实例化的原因。如果你想要在程序运行的时候动态往 Spring IOC 容器注册新的 bean,就会使用到这个类。那我们怎么在运行时获得这个实例呢?之前我们说过 ApplicationContext 接口能获取到 AutowireCapableBeanFactory,就是最右上角那个,然后它向下转型就能得到 DefaultListableBeanFactory 了。

========================================================
在继续往下之前,我们需要先了解 BeanDefinition。我们说 BeanFactory 是 Bean 容器,那么 Bean 又是什么呢?这里的 BeanDefinition 就是我们所说的 Spring 的 Bean,我们自己定义的各个 Bean 其实会转换成一个个 BeanDefinition 存在于 Spring 的 BeanFactory 中。所以,如果有人问你 Bean 是什么的时候,你要知道 Bean 在代码层面上可以认为是 BeanDefinition 的实例。(BeanDefinition 中保存了我们的 Bean 信息,比如这个 Bean 指向的是哪个类、是否是单例的、是否懒加载、这个 Bean 依赖了哪些 Bean 等等。)

package org.springframework.beans.factory.config;  源码就没必要贴了里面定义了很多描述bean的字段自己去看

有了 BeanDefinition 的概念以后,我们再往下看 refreshBeanFactory() 方法中的剩余部分:
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);

customizeBeanFactory(beanFactory) 比较简单,就是配置是否允BeanDefinition 覆盖、是否允许循环引用。上面代码中都有注释。

加载 Bean: loadBeanDefinitions

接下来是最重要的 loadBeanDefinitions(beanFactory) 方法了,这个方法将根据配置,加载各个 Bean,然后放到 BeanFactory 中。它的实现在子类中ctry+alt+B就能看到实现类

读取配置的操作在 XmlBeanDefinitionReader 中,其负责加载配置、解析。

初始化所有的 singleton beans

finishBeanFactoryInitialization(beanFactory);

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 注意了,初始化的动作包装在 beanFactory.getBean(...) 中,这里先不说细节,先往下看吧
		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));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		// 先初始化 LoadTimeWeaverAware 类型的 Bean
		// 之前也说过,这是 AspectJ 相关的内容,放心跳过吧
		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.
		// 没什么别的目的,因为到这一步的时候,Spring 已经开始预初始化 singleton beans 了,
		// 肯定不希望这个时候还出现 bean 定义解析、加载、注册。
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化所有的单例对象
		// 开始初始化
		/** {@link DefaultListableBeanFactory#preInstantiateSingletons()} */
		beanFactory.preInstantiateSingletons();
	}

invokeBeanFactoryPostProcessors(beanFactory);

执行当前spring项目中所有的BeanFactoryPostProcessors,在我们的spring内部自己提供了8个后安置处理器。在spring将所有的bean扫描装载到map中后,就会执行此方法如果我们提供了自定义的BeanFactoryPostProcessors(注意跟BeanPostProcessors的区别),就会执行其中的post Process BeanFactory(ConfigurableListableBeanFactory beanFactory)方法

preInstantiateSingletons

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		// 可能(lazy,scop)需要去实例化的class(前面已经将spring中符合规则的bean全部都扫描放入了concurrentHashMap中)
		// private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
		// 获取我们容器中所有bean的名称
		// this.beanDefinitionNames 保存了所有的 beanNames
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 触发所有非延迟加载单例bean的初始化
		for (String beanName : beanNames) {
			// 根据名字从map中循环拿出所有的bd对象
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);// 合并父BeanDefinition
			// 非抽象、非懒加载的 singletons。如果配置了 'abstract = true',那是不需要初始化的
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					// 如果是factorybean 则加上&
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						//
						if (isEagerInit) {
							//为什么是get?创建前需要判断是否已经创建
							getBean(beanName);
						}
					}
				}
				else {
					// 对于普通的 Bean,只要调用 getBean(beanName) 这个方法就可以进行初始化了
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// 到这里说明所有的非懒加载的 singleton beans 已经完成了初始化
		// 如果我们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里得到回调,忽略
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

在将BDname和BD对象放入到beanDefinitionMap中的同时,也把BDname都存入到了beanDefinitionNames 中,当我们去实例BD的时候首先会去list中循环把所有BD的名字拿出来进行一系列的判断,如果不是FactoryBean直接进入else分支。

/** List of bean definition names, in registration order. */
	private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

在判断为非懒加载,抽象后又进行了factoryBean的判断,什么是factoryBean?

FactoryBean:

面试中有时候会问到我们FactoryBean和BeanFactory的区别,我们应该如何回答。在源码级别spring对FactoryBean跟BeanFactory是不一样的。上面我们可以看到判断如果是FactoryBean就会在beanName前面加上&符号

FactoryBean 适用于 Bean 的创建过程比较复杂的场景,比如数据库连接池的创建。在很多框架内有用到factoryBean,如mybatis中想把一个mapper注入到spring中就是通过实现FactoryBean.

public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<T> getObjectType();
    boolean isSingleton();
}
public class Person { 
    private Car car ;
    private void setCar(Car car){ this.car = car;  }  
}

我们假设现在需要创建一个 Person 的 Bean,首先我们需要一个 Car 的实例,我们这里假设 Car 的实例创建很麻烦,那么我们可以把创建 Car 的复杂过程包装起来:

public class MyCarFactoryBean implements FactoryBean<Car>{
    private String make; 
    private int year ;

    public void setMake(String m){ this.make =m ; }

    public void setYear(int y){ this.year = y; }

    public Car getObject(){ 
      // 这里我们假设 Car 的实例化过程非常复杂,反正就不是几行代码可以写完的那种
      CarBuilder cb = CarBuilder.car();

      if(year!=0) cb.setYear(this.year);
      if(StringUtils.hasText(this.make)) cb.setMake( this.make ); 
      return cb.factory(); 
    }

    public Class<Car> getObjectType() { return Car.class ; } 

    public boolean isSingleton() { return false; }
}

我们看看装配的时候是怎么配置的:

<bean class = "com.javadoop.MyCarFactoryBean" id = "car">
  <property name = "make" value ="Honda"/>
  <property name = "year" value ="1984"/>
</bean>
<bean class = "com.javadoop.Person" id = "josh">
  <property name = "car" ref = "car"/>
</bean>

看到不一样了吗?id 为 “car” 的 bean 其实指定的是一个 FactoryBean,不过配置的时候,我们直接让配置 Person 的 Bean 直接依赖于这个 FactoryBean 就可以了。中间的过程 Spring 已经封装好了。说到这里,我们知道,现在还用 xml 配置 Bean 依赖的越来越少了,更多时候,我们可能会采用 java config 的方式来配置,这里有什么不一样呢?

@Configuration 
public class CarConfiguration { 

    @Bean 
    public MyCarFactoryBean carFactoryBean(){ 
      MyCarFactoryBean cfb = new MyCarFactoryBean();
      cfb.setMake("Honda");
      cfb.setYear(1984);
      return cfb;
    }

    @Bean
    public Person aPerson(){ 
    Person person = new Person();
      // 注意这里的不同
    person.setCar(carFactoryBean().getObject());
    return person; 
    } 
}

getBean(beanName);

下面才是最关键的方法,这个方法我们经常用来从 BeanFactory 中获取一个 Bean,而初始化的过程也封装到了这个方法里。

@SuppressWarnings("unchecked")
	// 我们在剖析初始化 Bean 的过程,但是 getBean 方法我们经常是用来从容器中获取 Bean 用的,注意切换思路,
   // 已经初始化过了就从容器中直接返回,否则就先初始化再返回
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		// 首先要对bean名字进行验证
		// 获取一个 “正统的” beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),
		// 一个是别名问题,因为这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是完全可以的
		final String beanName = transformedBeanName(name);

		// 注意跟着这个,这个是返回值
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		// spring中最经典重要,尝试去缓存中获取对象
		// 检查下是不是已经创建过了
		Object sharedInstance = getSingleton(beanName);


		// 这里说下 args 呗,虽然看上去一点不重要。前面我们一路进来的时候都是 getBean(beanName),
		// 所以 args 传参其实是 null 的,但是如果 args 不为空的时候,那么意味着调用方不是希望获取 Bean,而是创建 Bean
		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 + "'");
				}
			}

			// 下面这个方法:如果是普通 Bean 的话,直接返回 sharedInstance,
			// 如果是 FactoryBean 的话,返回它创建的那个实例对象
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			// 创建过了此 beanName 的 prototype 类型的 bean,那么抛异常,
			// 往往是因为陷入了循环引用,判断是否正在创建,如果正在创建会改变ThreadLocal<Object>中的值
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			/**
			 * 判断abstractBeanFactory工厂是否有父工厂(一般情况下是没有父工厂的)
			 */
			// 检查一下这个 BeanDefinition 在容器中是否存在
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				// 如果当前容器不存在这个 BeanDefinition,试试父容器中有没有
				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) {
				// typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。表示已经创建过一次
				markBeanAsCreated(beanName);
			}


			/*
			 * 稍稍总结一下:
			 * 到这里的话,要准备创建 Bean 了,对于 singleton 的 Bean 来说,容器中还没创建过此 Bean;
			 * 对于 prototype 的 Bean 来说,本来就是要创建一个新的 Bean。
			 */
			try {
				// 从容器中获取beanName对应的GenericBeanDefinition对象,并将其转化为RootBeanDefinition对象
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 检查当前定义的beanDefinition是否是抽象的
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				// 先初始化依赖的所有 Bean,这个很好理解。
				// 注意,这里的依赖指的是 depends-on 中定义的依赖。@DependsOn注解用于表示A创建前必须依赖B
				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 {
							// 先初始化被依赖项
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				// 创建单例bean
				// 如果是 singleton scope 的,创建 singleton 的实例,这里的 getSingleton与上面的不是同一个方法
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 执行创建 Bean,详情后面再说
							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;
						}
					});
					bean = 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);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				// 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								/** {@link AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])} */
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		// 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回了
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

1.getSingleton(第一个方法从单例池中拿拿不到到缓存池中拿,拿不到返回空,下面还有另一个getSingleton方法)

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// 从map中获取bean如果不为空直接返回,不再进行初始化工作
		// 一个程序员提供的对象这里一般为空
		// 这里涉及到解决循环引用问题,这里并不是从单例池中获取而是从缓存中
		Object singletonObject = this.singletonObjects.get(beanName);
		// isSingletonCurrentlyInCreation(beanName):判断这个对象是否在创建过程当中
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

spring如何解决循环依赖问题假设A依赖B,B依赖A。A在创建过程中发现需要B,此时就需要获取B但是B并不在单例池中,而是在三级缓存中

DefaultSingletonBeanRegistry
/** Cache of early singleton objects: bean name to bean instance. */
	// 存放原始的Bean对象用于解决循环依赖,注意存到里面的对象还没有被填充属性
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

singletonObjects是什么?
我们常说的spring容器就是这个map(从微观理解),更深入的理解应该是spring各个组件加在一起配合完成工作这么一个状态。

/** Cache of singleton objects: bean name to bean instance. */
	// 用于存放完全初始化好的bean从该缓存中取出的bean可以直接使用,单例池
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

2.getSingleton(从单例池拿,拿不到创建)

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 初始化bean这个过程其实是调用createBean方法
					/**{@link AbstractBeanFactory 369行} */
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					// 加入缓存中
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

在开始创建时会改变bean状态并放入set集合,表示正在创建。这里为了解决循环引用。A在创建前先会去getSingleton1()拿不到就会添加到earlySingletonObjects中表示此类spring即将创建。把name放入到set中并将状态改为True.然后调用AbstractAutowireCapableBeanFactory中creatBean()方法开始创建此时你它发现引用了B

// 会把正在创建的bean的name 放入到这个集合
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));
protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}
@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.
		// 确保 BeanDefinition 中的 Class 被加载
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		// 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />
		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.
			// 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理,
			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实例对象的过程
			// 重头戏,创建 bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			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);
		}
	}

doCreateBean

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

		// Instantiate the bean.
		// beanWrapper是对bean的包装啊,其接口中定义的功能很简单
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			// 从没有完成的factoryBean中移除
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 使用合适的实例化策略来创建新的实例
			// 说明不是 FactoryBean,这里实例化 Bean,这里非常关键,细节之后再说
			// 创建bean的实例并将实例包裹在BeanWrapper实现类对象中返回
			// createBeanInstance中包含三种创建bean实例的方式:1.通过工厂方法创建beanshili 2.通过构造方法自动注入 3.通过无参构造方法 ,若bean中配置了lookup-method,replace-method则会使用CGlib增强bean实例
			
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// 从wrapperBean中获取我们的早期对象
		// 这个就是 Bean 里面的 我们定义的类 的实例,很多地方我直接描述成 "bean 实例"
		final Object bean = instanceWrapper.getWrappedInstance();
		// 类型
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		// 建议跳过吧,涉及接口:MergedBeanDefinitionPostProcessor
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// 进行后置处理@autoWired的注解预解析
					// MergedBeanDefinitionPostProcessor,这个我真不展开说了,直接跳过吧,很少用的
					// 第三次执行后置处理器
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		// 下面这块代码是为了解决循环依赖的问题,以后有时间,我再对循环依赖这个问题进行解析吧
		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");
			}
			// 第四次执行后置处理器
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// 给我们的属性进行赋值(用set方法进行)
			// 这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
			populateBean(beanName, mbd, instanceWrapper);
			// 进行对象初始化操作这里可能生成代理对象
			// 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?
			// 这里就是处理 bean 初始化完成后的各种回调
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		// 确保已经加载了此 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<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		if (mbd.getFactoryMethodName() != null) {
			// 采用工厂方法实例化,不熟悉这个概念的读者请看附录,注意,不是 FactoryBean
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		// 如果不是第一次创建,比如第二次创建 prototype 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);
			}
		}

		// Candidate constructors for autowiring?
		// 判断是否采用有参构造函数
		// 第二次执行后置处理器,判断用哪个构造函数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			// 构造函数依赖注入
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		// 调用无参构造函数
		return instantiateBean(beanName, mbd);
	}

Bean注入模型

public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		GenericBeanDefinition test2 = (GenericBeanDefinition) beanFactory.getBeanDefinition("test2");
		test2.setAutowireMode(1);// 默认为0
	}
}

AutowireCapableBeanFactory中定义了:

int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
这里的byname并不是字面上理解根据名字注入这里很容易让人误解,当spring发现注入模型为byname时,在将当前对象new出来后进行自动装配。不会再去管类中属性而是把当前类带了set前缀的所有方法找出来。在spring内部有一个writeMetho(),必须是以set开头,set后面名字必须与容器中名字一致,且方法内参数必须在spring容器内。然后将符合要求的writeMetho方法利用反射method.invoke()进行属性注入,它本身其实和类中属性并没有任何关系
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;通过构造方法注入
@Deprecated
int AUTOWIRE_AUTODETECT = 4;

如何将一个对象交给spring管理:
1.@bean
2.annotationConfigApplicationContext.getBeanFactory().registerSingleton();
3.factoryBean

spring如何将一个对象new出来

发布了29 篇原创文章 · 获赞 11 · 访问量 1871

猜你喜欢

转载自blog.csdn.net/chihaihai/article/details/100749721
今日推荐