IoC容器加载过程和Bean的生命周期源码深度剖析

目录

1、this(); //获取组件

(1)DefaultListableBeanFactory

(2)BeanDefinitionReader

(3)BeanDefinitionScanner->扫描器,包扫描

2、register(componentClasses)—>注册BeanDefinition

3、refresh() 方法

(1)finishBeanFactoryInitialization—>生产Bean

(2)BeanFactory 和 FactoryBean的区别


Spring IoC加载过程图示,所有的源码跟进依据此图为大纲

从 ApplicationContext 开始,简单的Bean创建、获取和使用流程如下

public class MainStat {
	public static void main(String[] args) {
		//加载配置文件,生产Bean
		ApplicationContext context = new AnnotationConfigApplicationContext(Person.class);
		//获取Bean
		Person person = (Person) context.getBean("person");
		//使用Bean
		System.out.println(person.getName());
	}
}

首先,我们会去获取一个上下文  new AnnotationConfigApplicationContext();在AnnotationConfigApplicationContext() 中做了三件事情,如下

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		// 1-生成三大组件:BeanFactory、BeanDefinitionReader、BeanDefinitionScanner
		this();
		// 2-注册BeanDefinition——>registerBeanDefinition
		register(componentClasses);
		// 3-Spring重点->Bean生命周期的实现
		refresh();
	}

1、this(); //获取组件

调用 this() 方法,首先会加载父类 GenericApplicationContext.calss 的构造方法,如下

public GenericApplicationContext() {
        //1-获取Bean工厂
		this.beanFactory = new DefaultListableBeanFactory();
	}

然后调用 AnnotationConfigApplicationContext.class 自生的构造方法

public AnnotationConfigApplicationContext() {
		// 2-BeanDefinitionReader 读取器
		this.reader = new AnnotatedBeanDefinitionReader(this);
		// 3-BeanDefinitionScanner 扫描器
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

(1)DefaultListableBeanFactory //容器

为什么首先要获取DefaultListableBeanFactory?因为 BeanFactory 是 Spring Bean容器(IOC容器)的顶层核心接口,DefaultListableBeanFactory 实现了 BeanFactory 和 Bean定义注册器,它的依赖和继承关系图如下

(2)BeanDefinitionReader // Bean定义

从代码:this.reader = new AnnotatedBeanDefinitionReader(this);

一直往下跟进,直到找到 AnnotationConfigUtils#registerAnnotationConfigProcessors 方法。

在该方法中,我们能看到注册了一些处理器的Bean定义,比如ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor 等等 // 目的是准备一些后续需要用到的类

//注册一些配置的后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				//注册了实现Order接口的排序器
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			//设置@AutoWired的候选的解析器
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		/**
		 * 为我们容器中注册了解析我们配置类的后置处理器ConfigurationClassPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器中注册了处理@Autowired 注解的处理器AutowiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器中注册处理@Required属性的注解处理器RequiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalRequiredAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 为我们容器注册处理JSR规范的注解处理器CommonAnnotationBeanPostProcessor
		 * org.springframework.context.annotation.internalCommonAnnotationProcessor
		 */
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 处理jpa注解的处理器org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
		 */
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 处理监听方法的注解解析器EventListenerMethodProcessor
		 */
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 注册事件监听器工厂
		 */
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

#扩展点

我们以其中一个Processor来做示例,比如ConfigurationClassPostProcessor(会解析加了@Configuration的配置类等),它实现了BeanFactory的扩展点->BeanFactoryPostProcessor //对照流程图来看

注:PostProcessor是在 refresh() 中 invokeBeanFactoryPostProcessors(beanFactory) 中调用

(3)BeanDefinitionScanner->扫描器,包扫描

ClassPathBeanDefinitionScanner 主要根据路径来进行包扫描,scan() 方法中的 doScan();

public int scan(String... basePackages) {
		int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
        //包扫描
		doScan(basePackages);

		// Register annotation config processors, if necessary.
		if (this.includeAnnotationConfig) {
			AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
		}

		return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
	}

2、register(componentClasses)—>注册BeanDefinition

通过reader,封装BeanDefinition信息  //不断往后边跟,直到找到关键代码

public void register(Class<?>... annotatedClasses) {
		Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
        //使用reader进行注册
		this.reader.register(annotatedClasses);
	}

封装BeanDefinition信息,设置BeanDefinition的相关属性

最终通过DefaultListableBeanFactory 把 BeanDefinition put 到 beanDefinitionMap 中

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
		if (beanDefinition instanceof AbstractBeanDefinition) {
			//省略代码...
		}

		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			//省略大段代码...
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				// Still in startup registration phase
                // 同时往beanDefinitionMap 、beanDefinitionNames(生产Bean时用到) 中存值
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
        //省略大段代码...
	}

3、refresh() 方法

refresh() 方法中的关键代码

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//1-准备刷新上下文环境
			prepareRefresh();

			//2-告诉子类刷新内部bean工厂
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//3-对bean工厂进行填充属性
			prepareBeanFactory(beanFactory);

			try {
				//4-允许在上下文子类中对bean工厂进行后处理
				postProcessBeanFactory(beanFactory);

				//5-调用在上下文中注册为bean的工厂处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				//6-注册拦截bean创建的bean处理器
				registerBeanPostProcessors(beanFactory);

				//7-为此上下文初始化消息源-国际化
				initMessageSource();

				//8-为此上下文初始化事件多播
				initApplicationEventMulticaster();

				//9-初始化特定上下文子类中的其他特殊bean
				onRefresh();

				//10-检查侦听器bean并注册它们
				registerListeners();

				//11-实例化所有剩余的(非惰性初始化)单例。
				finishBeanFactoryInitialization(beanFactory);

				//12-最后一步:发布相应的事件。
				finishRefresh();
			}

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

				//销毁已经创建的单例以避免悬空的资源。
				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...
				// 重置Spring核心中常见的内省缓存,因为我们可能不再需要单例bean的元数据了。
				resetCommonCaches();
			}
		}
	}

Spring refresh() 方法中有很多方法,在此我们只关注IOC的加载流程和步骤,其他部分后续再详细拆分。

(1)finishBeanFactoryInitialization—>生产Bean

跟进去,找到创建Bean的代码,这段代码在 AbstractBeanFactory 中

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

            // 省略大段代码 ...
				// Create bean instance. 创建Bean实例
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
                            //创建Bean
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
          // 省略大段代码 ...  
}

具体实现代码如下,其中 doCreateBean(beanName, mbdToUse, args); 进行真正的Bean创建

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {  
        //省略大段代码...
		try {
			//实例创建前,第一次调用Bean的后置处理器-InstantiationAwareBeanPostProcessor
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				//如果后置处理器InstantiationAwareBeanPostProcessor(实现此接口)创建了Bean
				//将直接返回,不再执行后续的创建步骤
				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;
		}
        //省略代码...
	}

我们来详细看看这个方法里边的实现,代码如下,其中我们可以详细的看到Bean创建的生命周期(实例化—>属性赋值—>初始化

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//1-实例化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//获取到实例化对象,暂未赋值
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		//允许后处理器修改合并的bean定义。
		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;
			}
		}
		//解决循环依赖相关
		//缓存单例,以便能够解析循环引用,即使是由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 {
			//2-属性赋值
			populateBean(beanName, mbd, instanceWrapper);
			//3-初始化 ->一堆Aware的调用(更多的通过后置处理器调用)
			//调用初始化回调方法:(1)@PostConstruct(2)InitializingBean接口 (3)init-method
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			//省略代码...
		}
		//省略大段代码...
		return exposedObject;
	}

在Bean的初始化方法中(initializeBean(beanName, exposedObject, mbd)),我们可以看到Spring对一堆Aware方法的调用和一些初始化回调方法的调用

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//调用后置处理器 -> ApplicationContextAwareProcessor 一堆Aware
			//其中会调用初始化回调注解@PostConstruct
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//初始化回调方法 1-实现了InitializingBean接口, 2-init-method
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			//调用初始化后的后置处理器,AOP的动态代理实现就是在此处
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

最终Spring会把生成的Bean放入到一级缓存,Spring IOC的加载过程,也就到此结束了。

(2)BeanFactory 和 FactoryBean的区别

BeanFactory

BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口,也就是Spring IOC所遵守的最底层和最基本的编程规范。在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某种功能的实现。

FactoryBean

一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

public class Person implements FactoryBean {

	private String name;
	private String sex;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

	//实现了FactoryBean,最终获取到的实例是WoMen("Jerry",18) 而非 Person
	@Override
	public WoMen getObject() throws Exception {
		return new WoMen("Jerry",18);
	}
	//获取到的是WoMen类
	@Override
	public Class<?> getObjectType() {
		return WoMen.class;
	}
}

直接强转会报错,因为此时拿到的对象是WoMen

修改下类型接收类型,如下

如果需要强制获取Person的原装Bean,可以在BeanName前加 '&'

区别

BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个特殊的Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的,没有BeanFactory就没有Bean的存在。对于FactoryBean接口,被它修饰的Bean,将成为一个特殊的Bean,原本的Bean将被隐藏,而是由FactoryBean的getObject()返回最终的Bean。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值