SpringIOC

一、IOC容器核心接口 

SpringIOC_第1张图片

1.1、资源读取 BeanDefinitionReader 

SpringIOC_第2张图片

BeanDefinitionReader 

public interface BeanDefinitionReader {

	BeanDefinitionRegistry getRegistry();
    
	@Nullable
	ResourceLoader getResourceLoader();

	@Nullable
	ClassLoader getBeanClassLoader();

	BeanNameGenerator getBeanNameGenerator();

	int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;

	int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
	
	int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;

	int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
}

1、AbstractBeanDefinitionReader
抽象类,同时实现了 EnvironmentCapable 接口,提供环境的get和set方法。实现了BeanDefinitionReader的通用方法,如按路径读取Bean,根据资源读取Bean交由子类来实现。

2、PropertiesBeanDefinitionReader
具体实现类,可以从properties文件读取Bean定义信息。

3、XmlBeanDefinitionReader
具体实现类,可从XML文件读取Bean定义信息。

4、GroovyBeanDefinitionReader
具体实现类,可读取Groovy 语言写的Bean的定义信息。

5、AnnotatedBeanDefinitionReader
读取注解生成 BeanDefinition 并注册。

6、ClassPathBeanDefinitionScanner
扫描类路径生成 BeanDefinition 并注册。 

1.2、对象封装 BeanDefinition 

SpringIOC_第3张图片

记录Bean的相关信息,可设置及获取Bean的内容,如:Bean类名、作用域、是否懒加载、初始化方法名称、销毁方法名称、是否单例、是否原型、属性值等。

SpringIOC_第4张图片

1、AbstractBeanDefinition 
抽象类,根据 BeanDefinition 中定义的接口提供了相应的属性,实现了 BeanDefinition 中定义的一部分方法。
BeanDefinition 只定义了一系列的 get/set 方法,没提供属性,AbstractBeanDefinition 中将属性定义出来。

2、RootBeanDefinition 
常用的实现类,对应了一般的元素标签。

3、ChildBeanDefinition 
拥有从父 BeanDefinition 那里继承配置的能力。

4、GenericBeanDefinition 
可动态设置父 Bean,同时兼具 RootBeanDefinition 和 ChildBeanDefinition 的功能。

5、AnnotatedBeanDefinition 
表示注解类型 BeanDefinition,拥有获取注解元数据和方法元数据的能力。

6、AnnotatedGenericBeanDefinition 
使用了 @Configuration 注解标记配置类会解析为 AnnotatedGenericBeanDefinition。

1.3、对象工厂 BeanFactory 

SpringIOC_第5张图片

BeanFactory 接口 

提供对Bean的基本操作,实现类根据特点基本实现了对Bean的各种操作。

    getBean(String name):根据Bean的名称获取Bean对象。
    getBean(String name, Class requiredType):根据Bean的名称和类型获取Bean对象。
    getBean(Class requiredType):根据类型获取Bean对象。
    containsBean(String name):判断容器中是否包含指定名称的Bean对象。
    isSingleton(String name):判断指定名称的Bean对象是否为单例。
    isPrototype(String name):判断指定名称的Bean对象是否为原型。
    destroyBean(Object bean):销毁指定的Bean对象。
    destroy():销毁容器中的所有Bean对象。

HierarchicalBeanFactory 接口 

处理父子容器之间Bean关系,实现类:DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。

    getParentBeanFactory():获取当前容器的父容器。
    containsLocalBean(String name):判断当前容器是否包含指定名称的Bean对象。
    getBean(String name, Class requiredType, Object[] args):根据名称、类型和构造参数获取Bean对象。
    getParent():获取当前容器的父容器。
    containsBean(String name):判断当前容器及其父容器中是否包含指定名称的Bean对象。

ListableBeanFactory 接口:
用于获取容器中的Bean对象。

    getBeanDefinitionCount():获取容器中Bean定义的数量。
    getBeanDefinitionNames():获取容器中所有Bean定义的名称。
    getBeanNamesForType():获取指定类型的所有Bean定义的名称。
    getBeansOfType():获取指定类型的所有Bean对象。
    getBeanNamesForAnnotation():获取被指定注解标注的所有Bean定义的名称。
    getBeansWithAnnotation():获取被指定注解标注的所有Bean对象。

AutowireCapableBeanFactory 
自动装备功能,提供:实例化、属性填充、autowire自动装配bean、initializeBean 回调相关初始化方法等。

ConfigurableBeanFactory 

可配置,提供:setParentBeanFactory、setBeanClassLoader、addBeanPostProcessor等,配置bean工厂的方法。

ConfigurableListableBeanFactory 

实现了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory具备三者的功能,
    ignoreDependencyType(); 忽略给定依赖类型的自动装配,
    registerResolvableDependency(); 注册指定类型的依赖使用指定的对象进行注入等功能。

DefaultListableBeanFactory 

Spring的默认BeanFactory,综合上述所有功能,主要是对bean注册后的处理。

1.4、应用上下文 ApplicationContext 

1.Spring容器的启动入口,拥有众多接口的功能接口,继承ListableBeanFactory,可获取多个bean;继承HierarchicalBeanFactory接口,可在应用起多个BeanFactory,将多个BeanFactory设置父子关系。
2.ApplicationContext 接口中最后一个方法:AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException; 用来自动装配Bean。额外功能:消息国际化、事件发布、资源加载等。
3.实现类:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext 等。new ClassPathXmlApplicationContext("classpath:application.xml")构造方法,根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)。

SpringIOC_第6张图片

ApplicationContext 两个比较常用的实现类 

/**
 * 方式一:类路径方式加载,默认在类路径的根目录下(也就是src目录下)
 */
ApplicationContext ac1 = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerDao customerDao1 = (CustomerDao)ac1.getBean("customerDao"); 
System.out.println(customerDao1);

/**
 * 方式二:使用文件系统的方式初始化ioc容器
 */
//2.2 相对路径
ApplicationContext ac3 = new FileSystemXmlApplicationContext("./src/applicationContext.xml");
CustomerDao customerDao3 = (CustomerDao)ac3.getBean("customerDao"); 
System.out.println(customerDao3);

ApplicationContext 初始化的核心方法 

@Override
public void refresh() throws BeansException, IllegalStateException {
   // 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
   synchronized (this.startupShutdownMonitor) {

      // 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
      prepareRefresh();

      // 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
      // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
      // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
      prepareBeanFactory(beanFactory);

      try {
         // 【这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
         // 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。】

         // 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
         // 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
         postProcessBeanFactory(beanFactory);
         // 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法
         invokeBeanFactoryPostProcessors(beanFactory);          

         // 注册 BeanPostProcessor 的实现类,此接口两个方法: postProcessBeforeInitialization、postProcessAfterInitialization。这里仅仅是注册,之后会回调这两方法
		 /* 1、从bean工厂中获取到所有实现了BeanPostProcessor接口的bean;
			2、循环遍历扫描出的所有的 BeanPostProcessor,然后分别存放到前面定义的几个集合中;
			3、按优先级排序后,注册实现了 PriorityOrdered 接口的 BeanPostProcessor;
			4、按优先级排序后,注册实现了Ordered接口的 BeanPostProcessor;
			5、注册其他普通的 BeanPostProcessor;*/ 
         registerBeanPostProcessors(beanFactory);

         // 初始化当前 ApplicationContext 的 MessageSource,国际化这里就不展开说了,不然没完没了了
         initMessageSource();

         // 初始化当前 ApplicationContext 的事件广播器,这里也不展开了
         initApplicationEventMulticaster();

         // 从方法名就可以知道,典型的模板方法(钩子方法),不展开说
         // 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
         onRefresh();

         // 注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
         registerListeners();

         // 重点,重点,重点
         // 初始化所有的 singleton beans
         //(lazy-init 的除外)
         finishBeanFactoryInitialization(beanFactory);

         // 最后,广播事件,ApplicationContext 初始化完成,不展开
         finishRefresh();
      } catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         // 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // 把异常往外抛
         throw ex;
      } finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

1.Application 加载xml
2.AbstractApplicationContext 的refresh函数载入Bean定义过程
3.AbstractApplicationContext 子类的refreshBeanFactory()方法
4.AbstractRefreshableApplicationContext 子类的loadBeanDefinitions方法
5.AbstractBeanDefinitionReader 读取Bean定义资源
6.资源加载器获取要读入的资源
7.XmlBeanDefinitionReader 加载Bean定义资源
8.DocumentLoader 将Bean定义资源转换为Document对象
9.XmlBeanDefinitionReader 解析载入的Bean定义资源文件
10.DefaultBeanDefinitionDocumentReader 对Bean定义的Document对象解析
11.BeanDefinitionParserDelegate 解析Bean定义资源文件中的元素
12.BeanDefinitionParserDelegate 解析元素
13.解析元素的子元素
14.解析子元素
15.解析过后的BeanDefinition 在IoC容器中的注册(IoC容器的初始化结束)
16.DefaultListableBeanFactory 向IoC容器注册解析后的BeanDefinition(依赖注入开始)
17.AbstractBeanFactory 通过getBean向IoC容器获取被管理的Bean
18.AbstractAutowireCapableBeanFactory 创建Bean实例对象
19.createBeanInstance 方法创建Bean的java实例对象
20.SimpleInstantiationStrategy 类使用默认的无参构造方法创建Bean实例化对象
21.populateBean 方法对Bean属性的依赖注入
22.BeanDefinitionValueResolver 解析属性值
23.BeanWrapperImpl 对Bean属性的依赖注入 

1.5 、Bean后置处理器 BeanPostProcessor 

Bean被实例化后,到最终缓存到单例池之前,中间会经过Bean的初始化过程,如:属性的填充、初始方法init的执行等。
BeanPostProcessor是个接口,实现了该接口并被容器管理的 BeanPostProcessor,会在流程节点上被Spring自动调用。

SpringIOC_第7张图片

public interface BeanPostProcessor { 
    //bean初始化方法调用前被调用
    @Nullable 
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
        return bean; 
    } 
    //bean初始化方法调用后被调用
    @Nullable 
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
        return bean; 
    } 
} 

BeanPostProcessor  前置增强具体方法 applyBeanPostProcessorsBeforeInitialization():
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {
    Object result = existingBean;
    // 1、获取到当前工厂中注册的所有BeanPostProcessor后置处理器
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 2、执行每一个BeanPostProcessor的前置增强方法:postProcessBeforeInitialization()
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            // 3、如果postProcessBeforeInitialization()返回为空,则直接返回原始bean,将不会执行后续的BeanPostProcessor后置处理器的增强
            return result;
        }
        // 4、使用增强后的bean current,赋值给result,然后返回
        result = current;
    }
    return result;
}

BeanPostProcessor 后置增强具体方法 applyBeanPostProcessorsAfterInitialization():
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {
    Object result = existingBean;
    // 1、获取到工厂中注册的所有BeanPostProcessor后置增强器
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 2、执行BeanPostProcessor的后置增强方法postProcessAfterInitialization()
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            // 3、如果postProcessAfterInitialization()返回为空,则直接返回原始bean,将不会执行后续的BeanPostProcessor后置处理器的增强
            return result;
        }
        // 4、使用增强后的bean current,赋值给result,然后返回
        result = current;
    }
    return result;
}

三、实例管理(生命周期、单例、安全)

SpringIOC_第8张图片

Spring中bean的生命周期 
(1).Spring对bean进行实例化;
(2).Spring将值和bean的引用注入到bean对应的属性中;
(3).bean实现了BeanNameAware接口,Spring将bean的ID传递给setBean-Name()方法;
(4).bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将 BeanFactory 容器实例传入;
(5).bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext()方法,将bean所在的应用上下文的引用传入进来;
(6).bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法;
(7).bean实现了InitializingBean接口,Spring将调用它们的after-PropertiesSet()方法。类似地,
(8).bean使用initmethod声明了初始化方法,该方法也会被调用;
(9).bean实现了BeanPostProcessor接口,Spring将调用它们的post-ProcessAfterInitialization()方法;
(10).bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁;
(11).bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果bean使用destroy-method声明了销毁方法,该方法也会被调用。 

你可能感兴趣的:(java,开发语言)