Spring IoC

Posted x_k

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring IoC相关的知识,希望对你有一定的参考价值。

IoC设计与实现

Spring IoC设计与实现:BeanFactory和ApplicationContext
结构图:

BeanDefinition:对于IoC容器来说,就是对依赖反转模式中管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能的核心数据结构。
FactoryBean和BeanFactory区别:

名称FacotryBeanBeanFactory
实质FactoryBean
作用产生和修饰对象生成的工厂Bean管理所有的Bean
备注工厂Bean:产生BeanBean工厂:管理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

Spring中的IOC示例

《Spring揭秘》---- IoC容器及Bean的生命周期

spring之注解构造IOC

Spring IOC----容器刷新(refresh())之前

《Spring揭秘》——IOC梳理2(容器启动)