Spring IOC概论
一、概念
Spring通过一个配置文件描述Bean及Bean之间的依赖关系。利用Java语言的反射功能实例化Bean并建立Bean之间的关系。Spring的IoC容器在完成这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean实例代码、事件发布、资源装载等高级服务。
IoC(Inversion of Control)
“控制反转”,创建对象的权利,由程序员反转给了Spring容器。用来管理对象的实例化和初始化,以及对象从创建到销毁的整个生命周期。这些对象统称为Spring Bean,即Java对象,与new出来的对象一样。
- 谁控制谁
IoC 容器控制了对象。 - 控制什么
主要是外部资源获取。 - 为何反转
由容器查找及注入依赖对象,对象只是被动的接受依赖对象。 - 哪些方面反转
依赖对象的获取。
传统创建对象的过程,如图:
传统创建对象.png
IOC/DI容器创建对象:
IOC容器创建对象.png
二、Spring容器高层视图
Spring启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean之间的依赖关系,为上层应用提供准备就绪的运行环境。其中Bean缓存池为HashMap实现。
Spring 容器高层视图.png
三、IOC容器实现
IoC的实现,必须依赖DI,因为IoC只是负责对象的创建,而对象创建过程中需要将对象与对象的依赖进行实现。此时使用到的就是DI(Dependency Injection,依赖注入,它必须依赖于IoC)。
Spring 通过读取 XML 或 Java 注解中的信息来获取哪些对象需要实例化。
Spring 提供 2 种不同类型的 IoC 容器,即 BeanFactory 和 ApplicationContext 容器。
BeanFactory(简述)
BeanFactory是Spring框架的基础设施,面向Spring本身。
BeanFactory继承体系
BeanFactory体系结构图.png
- BeanDefinitionRegistry 注册表
Spring配置文件中每一个节点元素在Spring容器里都通过一个BeanDefinition对象表示,它描述了Bean的配置信息。而BeanDefinitionRegistry接口提供了向容器手工注册BeanDefinition对象的方法。 - BeanFactory顶层接口
位于类结构树顶端,它最主要的方法就是getBean(String beanName),该方法从容器中返回特定名称的Bean,BeanFactory的功能通过其他的接口得到不断的扩展。 - ListableBeanFactory
该接口定义了访问容器中Bean基本信息的若干方法,如查看Bean的个数、获取某一类型Bean的配置名、查看容器中是否包括某一Bean等方法。 - HierarchicalBeanFactory父子级联
父子级联IOC容器的接口,子容器可通过接口方法访问父容器;
通过HierarchicalBeanFactory接口,Spring的IOC容器可建立父子层次关联的容器体系,子容器可访问父容器中的Bean,但父容器不能访问子容器的Bean。Spring使用父子容器实现了很多功能,比如在Spring MVC中,展现层Bean位于一个子容器中,而业务层和持久层的Bean位于父容器中。这样,展现层Bean就可引用业务层和持久层的Bean,而业务层和持久层的Bean则看不到展现层的Bean。 - ConfigurableBeanFactory
一个重要接口,增强了IOC容器的可定制性,它定义了设置类装载器、属性编辑器、容器初始化后置处理器等方法。 - AutowireCapableBeanFactory自动装配
定义了将容器中的Bean按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法。 - SingletonBeanRegistry运行期间注册单例Bean
定义了允许在运行期间向容器注册单实例Bean的方法;
对于单实例(singleton)的Bean来说,BeanFactory会缓存Bean实例,所以第二次使用getBean()获取Bean时将直接从IOC容器的缓存中获取Bean是来。Spring在DefaultSingletonBeanRegistry类中提供了一个用于缓存单实例Bean的缓存器,它是一个用HashMap实现的缓存器,单实例的Bean以beanName为键保存在这个HashMap中。 - 依赖日志框架
在初始化BeanFactory时,必须为其提供一种日志框架,如Log4J,即在类路径下提供Log4J配置文件,这样启动Spring容器才不会报错。
ApplicationContext(简述)
ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合我们都直接使用ApplicationContext而非底层的BeanFactory。
ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用 的 功 能 。ApplicationContext 继承了 HierarchicalBeanFactory和ListableBeanFactory 接口,在此基础上,还通过多个其他的接口扩展了BeanFactory 的功能
ApplicationContext架构体系.png
- ClassPathXmlApplicationContext:默认从类路径加载配置文件。
- FileSystemXmlApplicationContext:默认从文件系统中装载配置文件。
- ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。
- MessageSource:为应用提供 i18n 国际化消息访问的功能。
- ResourcePatternResolver : 所 有 ApplicationContext 实现类都实现了类似于PathMatchingResourcePatternResolver 的功能,可以通过带前缀的 Ant 风格的资源文件路径装载 Spring 的配置文件。
- LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,主要用于控制异步处理过程。在具体使用时,该接口同时被 ApplicationContext 实现及具体Bean 实现, ApplicationContext 会将 start/stop 的信息传递给容器中所有实现了该接口的 Bean,以达到管理和控制 JMX、任务调度等目的。
- ConfigurableApplicationContext 扩展于 ApplicationContext,它新增加了两个主要
的方法: refresh()和 close(),让 ApplicationContext 具有启动、刷新和关闭应用上下
文的能力。在应用上下文关闭的情况下调用 refresh()即可启动应用上下文,在已经启动的状态下,调用 refresh()则清除缓存并重新装载配置信息,而调用 close()则可关闭应用上下文。
WebApplication体系结构
WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。从WebApplicationContext中可获得ServletContext的引用,整个Web应用上下文对象将作为属性放置到ServletContext中,以便Web应用环境可访问Spring应用上下文。
WebApplicationContext.png