Spring 容器
在 Spring 应用中,应用对象生存于 Spring 容器中,Spring 容器负责创建对象、装配对象、配置对象以及管理它们的整个生命周期。
如何理解容器 (container)
首先可以通过这篇了解下 DI 和 IoC ,链接。
容器是 Spring 的核心。Spring 容器使用 DI 管理构成应用的组件,它会创建相互协作的组件之间的关联。
两种 Spring 容器实现
- bean 工厂:由
org.springframework.beans.factory.BeanFactory接口定义,是最简单的容器,提供基本的 DI 支持。但是对于大多数应用来说太低级了,所以推荐使用下面一种。 - 应用上下文:由
org.springframework.context.ApplicationContext接口定义,基于 BeanFactory 构建,并提供应用框架级别的服务。以下讨论的都是这种容器实现。
常见的应用上下文
1. ClassPathXmlApplicationContext
从类路径下的一个或多个 XML 配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。
代码实现如下:
ApplicationContext context = new ClassPathXmlApplicationContext("knight.xml");
2. FileSystemXmlApplicationContext
从文件系统下的一个或多个 XML 配置文件中加载上下文定义。
代码实现如下:
ApplicationContext context = new FileSystemXmlApplicationContext("/User/ethan/knight.xml");
区别:ClassPathXmlApplicationContext 默认会去 classPath 路径下找。classPath 路径指的就是编译后的 classes 目录。FileSystemXmlApplicationContext 默认是去项目的路径下加载,可以是相对路径,也可以是绝对路径。
3.其他几种应用上下文
AnnotationConfigApplicationContextAnnotationConfigWebApplicationContextXmlWebApplicationContext
应用上下文准备就绪之后,就可以调用应用上下文的getBean()方法从 Spring 容器中获取 bean。
bean 的生命周期
传统的 java 应用中,生命周期就是 new 完就是创建了,一旦该 bean 不再被使用,由 Java 自动进行垃圾回收。
Spring 容器中的 bean 生命周期会复杂很多,具体如下:
-
Spring 对 bean 进行实例化
-
Spring 将值和 bean 的引用注入到 bean 对应的属性中
-
如果实现了下面接口,分别会做不同操作:
3.1 如果 bean 实现了
BeanNameAware接口,Spring 将bean 的 ID 传递给setBeanName()方法。关于BeanNameAware 以及下面的 BeanFactoryAware 可以查看这篇。Aware 这个词在这里可以翻译为知觉
3.2 如果 bean 实现了
BeanFactoryAware接口,Spring 将调用setApplicationCOntext()方法,将BeanFactory容器实例传入。方法本身的目的是让Spring立即处理工厂中所有Bean的定义,并且将这些Bean全部实例化。因为Spring默认实例化Bean的情况下,采用的是lazy机制,换言之,如果不通过getBean()方法(BeanFactory或者ApplicationContext的方法)获取Bean的话,那么为了节省内存将不实例话Bean,只有在Bean被调用的时候才实例化他们。
3.3 如果 bean 实现了
ApplicationContextAware接口,Spring 将调用setApplicationContext()方法,将 bean 所在的应用上下文实例传进来。在某些特殊的情况下,Bean需要实现某个功能,但该功能必须借助于Spring容器才能实现,此时就必须让该Bean先获取Spring容器,然后借助于Spring容器实现该功能。为了让Bean获取它所在的Spring容器,可以让该Bean实现ApplicationContextAware接口。
3.4 如果 bean 实现了
BeanPostProcessor接口,Spring 将调用setPostProcessBeforeInitialization()方法。如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。
3.5 如果 bean 实现了
InitializingBean接口,Spring 将调用afterPropertiesSet()方法。类似地,如果 bean 使用 init-method 声明了初始化方法,该方法也会被调用。InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。
3.6 如果 bean 实现了
BeanPostProcessor接口,Spring 将调用setPostProcessAfterInitialization()方法。类似3.4, 一前一后。 -
此时,bean 已经准备就绪,可以被应用程序使用了,它们将一直驻留在上下文中,知道该应用上下文被销毁。
-
如果 bean 实现了
DisposableBean接口,Spring 将调用它的destory()接口方法。同样,如果 bean 使用 destory-method 声明了 销毁方法,该方法也会被调用。










网友评论