深入理解Spring源码(开启篇)

由于平时项目中都会用到spring,但是一般都是已经配好了,我们直接使用即可,这段时间有点时间,就研究了下spring的源码,打算在近期详细的归纳一下spring容器是怎么运行管理bean的整个周期。



 

BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean。

Spring容器最基本的接口就是BeanFactor。BeanFactory负责配置、创建、管理Bean,他有一个子接口:ApplicationContext,因此也称之为Spring上下文。Spring容器负责管理Bean与Bean之间的依赖关系。

         BeanFactory接口包含以下几个基本方法:

             Ø Boolean containBean(String name):判断Spring容器是否包含id为name的Bean实例。

             Ø <T> getBean(Class<T> requiredTypr):获取Spring容器中属于requiredType类型的唯一的Bean实例。

             Ø Object getBean(String name):返回Sprin容器中id为name的Bean实例。

             Ø <T> T getBean(String name,Class requiredType):返回容器中id为name,并且类型为requiredType的Bean

             Ø Class <?> getType(String name):返回容器中指定Bean实例的类型。

         调用者只需使用getBean()方法即可获得指定Bean的引用,无须关心Bean的实例化过程。即Bean实例的创建过程完全透明。

         在使用BeanFactory接口时,我们一般都是使用这个实现类:org.springframework.beans.factory.xml.XmlBeanFactory。然而ApplicationContext作为BeanFactory的子接口,使用它作为Spring容器会更加方便。它的实现类有:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。



我们简单的拿出一个spring容器初始化的代码 这里我们拿出的是基于xml的方式  基于注解的也大同小异(后续有空也可以分享)

package com.test.main;

import com.test.seivice.CarService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {

	public static void main(String[] args) {

		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:game.xml");
		CarService testDao = (CarService) applicationContext.getBean("test");
		System.out.println(testDao);
	}
}

 

AplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:game.xml");  简单的一行代码就实现了spring 容器初始化的整个过程,这也就是我们开始研究的入口

我们点进 ClassPathXmlApplicationContext方法里面

	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

这是一个有参构造函数 我们继续点进去this方法

	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		// 这个地方 我们传进来的parent对象为空 一路断点进去  发现parent始终为空 我们尚且不关注
		super(parent);
		// 将配置文件路径设置给AbstractRefreshableConfigApplicationContext 的configLocations的属性
		setConfigLocations(configLocations);
		// 由上面的参数传进refresh为true 下面我们就进入refresh方法 spring初始化全程
		if (refresh) {
			refresh();
		}
	}

由上面的注释 我们得知refresh()方法是贯穿spring整个初始化的方法

@Override
	public void refresh() throws BeansException, IllegalStateException {

		//加锁 防止 fresh还没结束  就又进入改方法 导致容器初始化错乱
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//准备工作  初始化spring状态 使spring处于运行状态
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			//这一步主要作用是将配置文件定义解析成beanDefine 注册到beanFactory中
			//但是这里的bean并没有初始化出来 只是提取配置信息 定义相关的属性
			//将这些信息保存到beanDefineMap中(beanName->beanDefine)对应的map
			//我们将深入进去 仔细看看源码
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

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

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//重要
				postProcessBeanFactory(beanFactory);

                // Invoke factory processors registered as beans in the context.
				// 重要 在spring的环境中执行已经被注册的factory processors
				// 设置执行自定义的ProcessBeanFactory 和 spring内部的定义的
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有的singleton beans 到目前为止 我们已经完成了beanFactory的创建
				// 如果没有设置懒加载 spring会为我们初始化所有的bean
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
                } catch (BeansException ex) {
			    }
				// Destroy already created singletons to avoid dangling resources.
				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();
			}
		}
	}

 

建议读者下载spring源码  这样方便于注释 断点调式,下面一章我们来介绍下 prepareRefresh()方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值