天天看点

Spring IoC 容器1.Ioc 概述Java 反射Spring 资源访问BeanFactory 和 ApplicationContextBean 的生命周期

1.Ioc 概述

Ioc (Inverse of Control) 是 Spring 容器的内核,字面意思为控制反转,包括控制和反转两方面内容。具体指的是某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定,即由 Spring 容器借由 Bean 配置来进行控制。 DI(Dependency Injection) 的概念也可以用来代替 IoC,即让调用类对某一接口实现类的依赖关系由第三方注入。

(1)Ioc 的类型

Ioc 主要划分为3种类型:构造函数注入、属性注入、接口注入。

<1> 构造函数注入

通过调用类的构造函数,将接口实现类通过构造函数变量闯入。

<2> 属性注入

属性注入可以有选择地的通过 Setter 方法完成调用类所需依赖的注入。

<3> 接口注入

将调用类所有的依赖注入的方法抽取到一个接口中,调用类通过实现该接口提供的相应的注入方法完成注入。接口注入需要增加类的数目,不提倡。

(2)通过容器完成依赖关系的注入

Spring 即一个容器,它通过配置文件或注解描述类与类之间的依赖关系,自动完成类的初始化和依赖注入工作。

Java 反射

通过程序化方式间接对 Class 进行操作。Class 文件由类装载器装载后,在 JVM 中形成一份描述 Class 结构的元信息对象。java 允许用户借由这个元信息对象直接调用 Class 对象。

简单实例:

ClassLoder loader = Thread.currentThread().getContextClassLoader();//获取当前线程的ClassLoader
Class clazz = loader.loadClass("car");//通过全限定类名装载反射实例

Constructor cons = clazz.getDeclaredConstructor((Class[])null);
Car car = (Car)cons.newInstance();//获取类的默认构造器对象,并通过其实例化Car

Method setColor = clazz.getMethod("serColor",String.class);
setColor.invoke(car,"black");//通过反射方法设置属性
           

类装载器 ClassLoader

ClassLoader 工作机制

寻找类的字节码文件并构造出类在 JVM 内部表示对象的组件。

类转载器把类装入 JVM 的步骤:

(1)装载

(2)链接

(3)初始化

JVM 在运行时会产生3个 ClassLoader:根装载器、ExtClassLoader、AppClassLoader。根装载器时 ExtClassLoader 的父装载器,ExtClassLoader 是 AppClassLoader 的父装载器。根装载器负责 JRE 核心类库装载,C++ 编写,Java 中看不到。ExtClassLoader 负责装载 JRE 拓展目录 ext 中的 JAR 包。AppClassLoader 负责装载 Classpath 路径下的类包。

Spring 资源访问

资源访问接口 Resource

Resource 主要方法:

boolean exists():是否存在

boolean isOpen():是否打开

URL getURL() throws IOException:返回资源的 URL

File getFile() throws IOException:返回资源的 File 对象

InputStream getInputStream() throws IOException:返回资源对应的输入流

资源加载

不显示使用 Resource 实现类的情况下,仅通过资源地址的特殊标识访问对应资源

BeanFactory 和 ApplicationContext

Spring IoC 完成底层的 Bean 之间的依赖关系建立,还提供 Bean 实例缓存、生命周期管理、Bean 实例代理、事件发布、资源装载等。

BeanFactory 是 Spring 的核心接口,提供 IoC 配置机制,面向 Spring 本身;ApplicationContext 建立在 BeanFactory 基础之上,提供面向应用的功能,面向使用 Spring 的开发者。

BeanFactory

BeanFactory 最主要的方法就是 getBean(String beanName),该方法从容器中返回特定名称的 Bean。

BeanFactory 的接口 XmlBeanDefinitionReader 通过 Resource 装载 Spring 配置信息并启动 IoC 容器,然后就可以通过 BeanFactory#getBean(beanName) 方法从 IoC 容器中获取 Bean。

对于单实例(singleton)的 Bean 来说,第二次使用 getBean() 获取该 Bean 时,将直接从 IoC 容器缓存中获取该 Bean。DefaultSingletonBeanRegistry 类提供一个用于缓存单实例 Bean 的缓存器 (HashMap 实现)。

ApplicationContext

ApplicationContext 的主要实现类是 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件。

ApplicationContext 会在初始化时就实例化所有单实例的 Bean。而 BeanFactory 只有在第一次访问某个 Bean 时才实例化目标 Bean。

Spring 子项目 JavaConfig 提供了基于注解的配置方式

Spring 为基于注解类的配置提供了专门的 ApplicationContext 实现类:AnnotationConfigApplicationContext

基于 Groovy 的配置方式

Spring 为基于 Groovy 类的配置提供了专门ApplicationContext 实现类:GenericGroovyApplicationContext

WebApplicationContext

WebApplicationContext 可以获得 ServletContext 的引用。

非 Web 环境中 Bean 只有 singleton 和 prototyte 两种作用域,而WebApplicationContext 添加了三个新的作用域:request、session、global session。

WebApplicationContext 只有在拥有 Web 容器的前提下才能启动工作

父子容器

通过 HierarchicalBeanFactory 接口,Spring IoC 容器可以建立父子层级关联的容器体系,子容器可以访问父容器,而父容器不能访问子容器。

Bean 的生命周期

BeanFactory 中 Bean 的生命周期

(1)通过 getBean()请求 Bean 时,调用 InstantiationAwareBeanPostProcessor 接口的 postProcessBeforeInstantiation() 方法。

(2)实例化 Bean。

(3)调用InstantiationAwareBeanPostProcessor 接口的 postProcessAfterInstantiation() 方法。

(4)设置 Bean 属性前调用InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues()方法。

(5)调用 Bean 的属性设置方法设置属性值。

(6)调用 setBeanName()接口方法。

(7)调用 setBeanFactory()接口方法。

(8)调用 BeanPostProcessor 的 postProcessBeforeInitialization(Object name,String beanName)方法。AOP,动态代理都通过 BeanPostProcessor 实施。

(9)调用 afterPropertiesSet()方法。

(10)执行 Bean 的初始化方法。

(11)对 Bean 加工处理。

(12)将 “prototype” 的 Bean 返回给调用者,Spring 不再负责这些 Bean 生命管理。将 “singleton” 的Bean 放入 IoC 容器的缓存池中。并将 Bean 引用返回给调用者,Spring 继续负责这些 Bean 生命管理。

(13)“singleton” Bean 的释放资源,记录日志操作。

(14)“singleton” Bean 的销毁。

ApplicationContext 中 Bean 的生命周期

如果 Bean 实现了 ApplicationContextAware 接口,则会增加一个调用该接口的方法 setApplicationContext() 的步骤。

  • 《精通 Spring4.x 企业应用》学习笔记*