IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> IoC容器加载过程和Bean的生命周期源码深度剖析 -> 正文阅读

[Java知识库]IoC容器加载过程和Bean的生命周期源码深度剖析

目录

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

(1)DefaultListableBeanFactory

(2)BeanDefinitionReader

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

2、register(componentClasses)—>注册BeanDefinition

3、refresh() 方法

(1)finishBeanFactoryInitialization—>生产Bean

(2)BeanFactory 和 FactoryBean的区别


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

简单的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(),调用AnnotationConfigApplicationContext的构造方法,首先会加载父类(GenericApplicationContext)的构造方法,如下

public GenericApplicationContext() {
        //1-获取Bean工厂
		this.beanFactory = new DefaultListableBeanFactory();
	}
public AnnotationConfigApplicationContext() {
		// 2-BeanDefinitionReader 读取器
		this.reader = new AnnotatedBeanDefinitionReader(this);
		// 3-BeanDefinitionScanner 扫描器
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

(1)DefaultListableBeanFactory

关于DefaultListableBeanFactory,依赖和继承关系图,它实现了Bean工厂和Bean注册器

(2)BeanDefinitionReader

在Reader中,注册了一些配置的后置处理器,比如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。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:33:33  更:2022-05-01 15:37:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:44:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码