Spring源码阅读 - IOC

① 定位:定位资源文件(定位配置文件或扫描相关注解)

② 加载:解析配置信息

③ 注册:将Bean的信息表示解析成BeanDefinition注册到BeanDefinitionMap

ClassPathXmlApplicationContext:

  1. 初始化资源加载器:AbstractApplicationContext()
// AbstractApplicationContext类
	public AbstractApplicationContext() {
		this.resourcePatternResolver = getResourcePatternResolver();
	}
	
	//获取一个Spring Source的加载器用于读入Spring Bean定义资源文件
	protected ResourcePatternResolver getResourcePatternResolver() {
		//AbstractApplicationContext继承DefaultResourceLoader,因此也是一个资源加载器
		return new PathMatchingResourcePatternResolver(this);
	}
  1. 设置资源路径:setConfigLocations(configLocations);

  2. 容器初始化AbstractApplicationContext#refresh()

   // ClassPathXmlApplicationContext类
   public ClassPathXmlApplicationContext(
       String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)      throws BeansException {
       // IOC 1:初始化资源加载器   
       super(parent);   
       // IOC 2: 设置资源路径   
       setConfigLocations(configLocations);      
       if (refresh) {      
           // IOC 3:IOC容器初始化入口,重启、刷新、重置、相关组件初始化
           // AbstractApplicationContext#refresh()
           refresh();   
       }}
  • 刷新bean factory:AbstractRefreshableApplicationContext#refreshBeanFactory()

+ View Code

  • 加载BeanDefinitions(子类实现):AbstractXmlApplicationContext#loadBeanDefinitions()

+ View Code

  • 解析资源文件,并注册到BeanDefinitionMap:XmlBeanDefinitionReader#doLoadBeanDefinitions()

+ View Code

AnnotationConfigApplicationContext

  1. 初始化注解Bean读取器和包路径扫描器:AnnotationConfigApplicationContext()

+ View Code

  • 直接注册:register(Class<?>... annotatedClasses)
// IOC 2 :为容器注册一个要被处理的注解Bean,必须手动调用容器的refresh()方法刷新容器,触发容器对新注册的Bean的处理
public void register(Class<?>... annotatedClasses) {   
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");     this.reader.register(annotatedClasses);
}
  • 设置扫描路径:scan(String... basePackages)
// IOC 2 :扫描指定包路径及其子包下的注解类,为了使新添加的类被处理,必须手动调用refresh()方法刷新容器
public void scan(String... basePackages) {   
	Assert.notEmpty(basePackages, "At least one base package must be specified");   		this.scanner.scan(basePackages);
}
posted @   祁奇  阅读(81)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示