Spring IOC解析

1 篇文章 0 订阅
Spring IOC解析

问题:Spring怎么加载配置文件,怎么注册bean,怎么获取bean

1.XmlBeanFactory

  1. new Resource(ClassPathResource 实现类获取bean配置文件和当前类加载器)传给XmlBeanFactory构造方法
	ClassPathResource resource = new ClassPathResource("beans.xml");
	XmlBeanFactory factory = new XmlBeanFactory(resource);
	UserDto userDto = factory.getBean("userDto", UserDto.class);
<1>初始化XmlBeanDefinitionReader

<2>调用XmlBeanDefinitionReader.loadBeanDefinitions方法
	<1>:创建Set<EncodedResource>集合添加到resourcesCurrentlyBeingLoaded
	
	<2>:InputStream inputStream = encodedResource.getResource().getInputStream();获取xml输入流
	
	<3>:InputSource inputSource = new InputSource(inputStream);转换为资源输入流
	
	<4>:调用doLoadBeanDefinitions获取配置文件Doucment ->调用doLoadDocument(获取配置文件的xsd约束文件)
		->DefauktDocumentLoader.loadDocument,DocumentBuilder builder.parse(inputSource)解析
	
	<5>:解析完成后调用XmlBeanDefinitionReader.registerBeanDefinitions
		->初始化BeanDefinitionDocumentReader
		->获取容器之前的数量(DefaultListableBeanFactory.beanDefinitionMap<String, BeanDefinition>.size())
		->doRegisterBeanDefinitions
			->preProcessXml(root);解析之前
			->DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(root, this.delegate);
				
				->parseDefaultElement(对比是否是
				  import:importBeanDefinitionResource,
				  alias:processAliasRegistration,
				  bean:processBeanDefinition,
					->BeanDefinitionParserDelegate.parseBeanDefinitionElement 负责解析元素
						->获取标签id和name属性
						->checkNameUniqueness将获取的id和name值保存在usedNames Set集合里面
						->parseBeanDefinitionElement 将bean名称保存到Stack<Entry>
						->parseBeanDefinitionAttributes 处理默认值以及填写的属性值					
				  beans:doRegisterBeanDefinitions)

			->DefaultListableBeanFactory.beanDefinitionMap.put(beanName,beanDefinition)
			->DefaultListableBeanFactory.beanDefinitionNames.add(beanName)
			->DefaultListableBeanFactory.manualSingletonNames.remove(beanName)

			->BeanComonentDefintion.findInnerBeanDefinitionsAndBeanReferences获取property设置的值存放在beanDefinition(所有配置文件的元数据都保存在这里,通过反射获取这里配置组装Bean)
			->postProcessXml(root);解析之后
	<6>:获取Bean
		BeanDefintionValueResover负责将property值赋值给Bean
  1. Ioc容器初始化过程,分为三个过程(1.BeanDefinition的Resouce定位,2.加载解析,3注册)

    1. 通过ResourceLoader读取以Resource定义的BeanDefinition
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
		throws BeansException {

	super(parent);
	setConfigLocations(configLocations);
	if (refresh) {
		//触发容器初始化,以及解析BeanDefinition
		refresh();
	}
}
//AbstractRefreshableApplicationContext,该类是AbstractApplicationContext基类
protected final void refreshBeanFactory() throws BeansException {
	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	try {
		//创建容器
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		beanFactory.setSerializationId(getId());
		customizeBeanFactory(beanFactory);
		//解析BeanDefinition
		loadBeanDefinitions(beanFactory);
		synchronized (this.beanFactoryMonitor) {
			this.beanFactory = beanFactory;
		}
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// Create a new XmlBeanDefinitionReader for the given BeanFactory.
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// Configure the bean definition reader with this context's
	// resource loading environment.
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

	// Allow a subclass to provide custom initialization of the reader,
	// then proceed with actually loading the bean definitions.
	initBeanDefinitionReader(beanDefinitionReader);
	loadBeanDefinitions(beanDefinitionReader);
}
  1. 通过XmlBeanDefinitionReader.loadBeanDefinitions解析载入BeanDefinition(这里解析的是XML其他形式可以由具体的BeanDefinitionReader基类解析)
    具体的解析完成是在BeanDefinitionParserDelegate中完成

  2. DefaultListableBeanFactory 负责将解析好的BeanDefinition注册到ioc容器中,该容器是一个HashMap
    beanDefinitionMap.put(beanName,beanDefinition)

  3. BeanFactroy根据组装好的BeanDefinition进行注入

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值