Spring IoC
Posted x_k
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring IoC相关的知识,希望对你有一定的参考价值。
IoC设计与实现
Spring IoC设计与实现:BeanFactory和ApplicationContext
结构图:
BeanDefinition:对于IoC容器来说,就是对依赖反转模式中管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能的核心数据结构。
FactoryBean和BeanFactory区别:
名称 | FacotryBean | BeanFactory |
---|---|---|
实质 | Factory | Bean |
作用 | 产生和修饰对象生成的工厂Bean | 管理所有的Bean |
备注 | 工厂Bean:产生Bean | Bean工厂:管理Bean |
BeanFacotry:
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
public interface BeanFactory
// 转移符来得到BeanFacotry本身
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String name) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
// 判断容器是否含有指定名称Bean
boolean containsBean(String name);
// 查询指定名称的Bean是否是Singleton类型(Singleton可以在BeanDefinition指定)
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
// 指定名称的Bean的Class类型
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
// 通过别名
String[] getAliases(String name);
BeanFactory容器设计原理
XmlBeanFactory结构图:
从上图可以看出XMLBeanFacotry只提供最基本的IoC容器的功能。
在Spring中,实际上是把DefaultListableBeanFactory作为一个默认的功能完整的IoC容器。
ApplicationContext应用原理
相比BeanFacotry提供了多种新特性:
支持不同的信息源,扩展了接口MessageSource。
访问资源,支持ResourceLoader和Resource。
支持应用事件,继承接口ApplicationEventPublisher
FileSystemXmlApplicationContext主要功能在其基类AbstractXmlApplicationContext实现,只需要启动IoC容器的refresh()和加载xml的Bean定义资源。
IoC初始化过程
1.Resource定位:BeanDefinition的资源位置
FileSystemXmlApplicationContext定位Resource过程:
FileSystemXmlApplicationContext :
package org.springframework.context.support;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resourcepublic class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext
public FileSystemXmlApplicationContext()
public FileSystemXmlApplicationContext(ApplicationContext parent)
super(parent);
// 包含BeanDefinition的所在文件路径
public FileSystemXmlApplicationContext(String configLocation) throws BeansException
this(new String[] configLocation, true, null);
// 包含BeanDefinition的所在多个文件路径
public FileSystemXmlApplicationContext(String... configLocations) throws BeansException
this(configLocations, true, null);
// 包含BeanDefinition的所在多个文件路径,并指定双亲IoC
public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException
this(configLocations, true, parent);
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException
this(configLocations, refresh, null);
// 调用refresh()载入BeanDefinition
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException
super(parent);
setConfigLocations(configLocations);
if (refresh)
refresh();
// 文件系统Resource的实现,BeanDefinitionReader的loadBeanDefinition中被调用
@Override
protected Resource getResourceByPath(String path)
if (path != null && path.startsWith("/"))
path = path.substring(1);
return new FileSystemResource(path);
详细过程:
1.FileSystemXmlApplicationContext -> refresh()
2.AbstractApplicationContext.refresh()-> obtainFreshBeanFactory()
3.AbstractApplicationContext.obtainFreshBeanFactory() -> refreshBeanFactory()
4.AbstractRefreshableApplicationContext.refreshBeanFactory() -> loadBeanDefinitions(beanFactory)
5.AbstractXmlApplicationContext.loadB eanDefinitions(DefaultListableBeanFactory beanFactory) -> loadBeanDefinitions(beanDefinitionReader)
6.AbstractXmlApplicationContext.loadBeanDefinitions(XmlBeanDefinitionReader reader) -> reader.loadBeanDefinitions(configLocations)
7.AbstractBeanDefinitionReader.loadBeanDefinitions(String... locations) -> loadBeanDefinitions(location)
8.AbstractBeanDefinitionReader.loadBeanDefinitions(String location) -> loadBeanDefinitions(location, null)
9.AbstractBeanDefinitionReader.loadBeanDefinitions(String location, Set<Resource> actualResources) -> resourceLoader.getResource(location)
10.DefaultResourceLoader.getResource(String location)
2.BeanDefinition载入和解析:用户定义的Bean表示成IoC容器内部数据结构和IoC容器内部将BeanDefinition注入到HashMap中
具体载入过程:XmlBeanDefinitionReader.registerBeanDefinitions(Document doc, Resource resource)
1.XML转换成document对象DefaultBeanDefinitionDocumentReader.processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate),由BeanDefinitionHolder持有
2.document对象转换成BeanDefinition对象BeanDefinitionReaderUtils.registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
3.Bean详细解析位置BeanDefinitionParserDelegate.parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean)
3.BeanDefinition在IoC容器中注册:通过HashMap持有载入的BeanDefinition
DefaultListableBeanFacotry:
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64)
DefaultListableBeanFactory.registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
以上是关于Spring IoC的主要内容,如果未能解决你的问题,请参考以下文章
《Spring揭秘》---- IoC容器及Bean的生命周期