美文网首页
spring-ioc容器

spring-ioc容器

作者: 不忘初心_23a0 | 来源:发表于2019-08-28 12:43 被阅读0次

IOC(inverse of control,控制-反转)

一、ioc概述

1.ioc的类型

    ioc主要可以划分成三种类型:构造函数注入、属性注入和接口注入

2.通过容器完成依赖关系注入:

    通过xml的方式配置Bean,在容器启动时,spring根据xml配置文件的
    描述信息自动实例化Bean并完成依赖关系的装配,
    这种实例化并注入依赖的能力是通过java的反射来实现的

二、相关java基础知识

java语言允许通过程序化的方式间接对Class进行操作。
Class文件有类装载器装载后, 在JVM中将形成一份描述Class结构的元信息对象,
通过该元信息对象可以获知Class的结构信息,如构造函数、属性和方法等。
Java允许用户借由这个与Class相关的元信息对象间接调用Class对象的功能,
这就为使用程序化方式操作Class对象开辟了途径

1、类装载器就ClassLoader

类装载器就是寻找类的字节码文件并构造出类在JVM内部表示对象的组件
类装载器把一个类装入JVM中,需要经过一下步骤:
(1)装载:查找和导入Class文件
(2)链接:执行校验、准备和解析步骤,其中解析步骤是可以选择的。
    ①校验:检查载入Class文件数据的正确性
    ②准备:给类的静态变量分配存储空间
    ③解析:将符号引用转换为直接引用
(3)初始化:对类的静态变量、静态代码块执行初始化工作
JVM装载类的时使用“全盘负责委托机制”
“全盘负责”:是指当一个ClassLoader装载一个类时,除非显式地使用另一个“ClassLoader”,
该类所依赖及引用的类也有这个ClassLoader载入;

“委托机制”:是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找
并装载目标类;

正因为有了“全盘负责委托机制”,java.lang.String 永远是由根装载器来装载的,
避免有人编写一个恶意的基础类(例如String)装载到JVM中

2.java反射机制

Class反射对象描述类的语义结构,
从Class对象可以获取构造函数、成员变量、方法类等类元素的反射对象
主要的反射类有三个:Controller、Method、Field  其他还有package、AnnotatedElement反射类
在访问private或protected成员变量或方法时,必须通过setAccessible(boolean access)方法取消
java语言检查,否则将抛出IllegalAccessException

三、资源访问利器 Resource

1、资源抽象接口

spring Resource接口为应用提供了更强的底层资源访问能力。该接口拥有对应不同资源类型的实现类
主要方法:
    > boolean exists(): 资源是否存在
    > boolean isOpen(): 资源是否打开
    > URL getUTL() throws IOException: 如果底层资源可以表示成URL,则该方法返回对应不同类型的实现类
    > File getFile() throws IOException: 如果底层资源对应一个文件,则该方法返回对应的File对象
    > InputStream getInputStream() throws IOException: 返回资源对应的输入流
> WritableResource: 可写资源接口 实现类有FileSystemResource和PathResource
> ByteArrayResource: 二进制数组表示的资源
> ClassPathResource: 类路径下的资源
> FileSystemResource: 文件系统资源
> InputStreamResource: 以输入流返回表示的资源
> ServletContextResource: 为访问Web容器上下文中的资源而设计的类
> UrlResource: 使用户能够访问任何可以通过URL表示的资源
> PathResource: spring4.0提供读取资源文件的一个通用类

2、资源加载

spring能通过不同的资源地址前缀识别不同的资源类型。支持Ant风格通配符资源地址:? * **
资源地址前缀有:classpath:、file:、http://、ftp://等。
或者是没有前缀,根据ApplicationContext的具体实现类采用对应类型的Resource

在发布时如果资源配置文件被打包到jar包中。recource.getFile就无法读取了,
从而造成部署实施时出现意想不到的问题。因此我们建议尽量以流的方式读取
避免环境不同造成问题

四、BeanFactory和ApplicationContext

spirng通过配置文件描述Bean与Bean之间的依赖关系,利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。
springIOC的容器在完成这些底层工作的基础上还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、资源装载等高级服务。
BeanFactory是spring框架最核心的接口,它提供了高级IOC的配置机制
BeanFactory是IOC容器,ApplicationContext为应用上下文,也称为Spring容器
BeanFactort是Spring框架的基础设施面向Spring本身;ApplicationContext面向使用Spring框架的开发者

1.BeanFactory在初始化容器时没有实例化Bean,直到第一次访问某个Bean时才实例化目标Bean
  而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。
    因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有“第一次惩罚”的问题

2.通过HierarchicalBeanFactory接口,spring的IOC容器可以建立父子层级关联的容器体系
    子容器可以访问父容器中的Bean,但父容器不能访问子容器中的Bean。
    在容器内,Bean的Id必须是唯一的,但子容器可以拥有一个和父容器id相同的Bean。

五、Bean的生命周期

Bean生命周期多个特定的生命阶段组成,每个生命阶段都开出了一扇门,允许外界借由此门对Bean施加控制
spring中可以从两层面定义Bean的生命周期: 
    第一个层面是Bean的作用范围
    第二个层面是实例化Bean时所经历的一系列阶段

1.BeanFactory中Bean的生命周期

1.当调用者通过getBean(beanName)向容器请求某一个Bean时,如果容器注册了
    org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口
  ,实例化Bean之前,将调用接口的postProcessBeforeInstantiation方法。
2.根据配置情况调用Bean构造函数或工厂方法实例化Bean
3.如果容器注册了InstantiationAwarePostProcessor接口,那么在实例化Bean之后,
  用该接口的postProcessAfterInstantiation()方法,可在这里对已经实例化的对象进行梳理打扮
4.如果Bean配置了属性信息,那么容器在这一步着手将配置值设置到Bean对应的属性中,不过在设置每个属性之前
  将先调用InstantiationAwareBeanPostProcessor接口的postProcessValues()方法。
5.调用Bean的属性设置方法设置属性值
6.如果Bean实现了 org.springframework.beans.factory.BeanNameAWare 接口,则将调用setBeanName()接口方法,
  将配置文件中该Bean对应的名称设置到Bean中
7.如果Bean实现了org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory()接口方法,
  将BeanFactory容器实例设置到Bean中。
8.如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,
  则将嗲用BeanPostProcessor的Object postProcessBeforeInitialzation(Object bean,String beanName)接口方法
  对Bean进行加工操作。
    其中入参bean是当前正在处理的Bean,而beanName是当前Bean的配置名,返回的对象为加工处理后的Bean
    用户可以使用该方法对某些Bean进行特殊处理,甚至改变Bean的行为。
    BeanPostProcessor在Spring框架中占有重要的地位,为容器提供对Bean后续加工处理的切入点
    Spring提供的AOP、动态dialing等功能都通过BeanPostProcessor实施
9.如果Bean实现了InitialzaingBean接口,则将调用接口的afterPropertiseSet()方法
10.如果<bean>中通过init-method属性定义了初始化方法,则将执行这个方法。
11.BeanPostProcessor后处理器定义了两个方法:
    其一是postProcessBeforeInitialization(),在第8步调用;
    其二是Object postProcessAfterInitialization(Object bean,String beanName),这个方法在此时调用,
          容器再次获得对Bean进行加工处理的机会
12.如果在<bean>中指定Bean的作用范围为scope = "prototype",则将Bean返回给调用者,调用者负责Bean后续的生命管理,
   spring不再管理这个Bean的生命周期。如果将作用范围设置为scope="singleton",则将Bean放入SpringIoc容器的缓存池中,
   并将Bean引用返回给调用者,Spring继续对这些Bean进行后续的生命管理。
13.对于scope="singleton"的Bean(默认情况),当容器关闭时,将触发Spring对Bean后续生命周期的管理工作。
   如果Bean实现了DisposableBean接口,将调用接口destroy方法,可以在此编写释放资源,记录日志等操作。
14.对于scope="singleton"的Bean,如果通过<bean>的destroy-method属性指定了Bean的销毁方法,那么Spring将执行Bean等的这个方法,
  完成Bean资源的释放等操作。

BeanFactory生命周期总结

Bean完整的生命周期中方法大致可以分为四类:
    1.Bean自身的方法:
        如调用Bean构造函数实例化Bean、调用Setter设置Bean的属性值及通过<bean>的init-method和destroy-method所指定的方法
    2.Bean级生命周期接口方法:
        如BeanNameAware、BeanFactoryAware、InitializatingBean和DisposableBean,这些接口方法有Bean类直接实现
    3.容器级生命周期接口方法:
        由InstantiationAwareBeanPostProcessor和BeanPostProcessor这两个接口实现的,一般称他们的实现类为“后处理器”。
        后处理器接口一般不由Bean本身实现,他们独立于Bean,实现类以容器附加装置的形式注册到Spring容器中,并通过接口
        反射为Spring容器扫描识别。当Spring容器创建任何Bean的时候,这些后处理器都会发生作用,所以这些处理器的影响是全局性的。
        当然,用户可以通过合理地编写后处理器,让其仅对感兴趣的Bean进行加工处理
    4.工厂后处理器接口方法:
         包括AspectJWeavingEnable、CustomerAutowireConfigurer、ConfigurationClassPostProcessor等方法。
         工厂后处理器也是容器级的,在应用上下文装配配置文件后立即调用

2.ApplicationContext中Bean的生命周期

1、Bean在应用上下文中的生命周期与在BeanFactory中类似,不同的是在第一步前如果配置了工厂后处理器接口BeanFactoryPostProcessor
   的实现类,则在应用上下文加载配置后,初始化Bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理。
   工厂后处理器是容器级的,仅在应用上下文初始化时调用一次,其目的是完成一些配置文件的加工处理工作
2.如果Bean实现了org.springframework.context.ApplicationContextAware接口,则会在第八步setBeanFactory后
  调用setApplicationContext方法
3.ApplicationContext与BeanFactory的另一个最大不同是:
    ApplicationContext会利用java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor
    和BeanFactoryPostProcessor,并自动将它们注册到上下文中
    BeanFactory则在代码中通过手工调用addBeanPostProcessor()方法进行注册

相关文章

网友评论

      本文标题:spring-ioc容器

      本文链接:https://www.haomeiwen.com/subject/xbrpectx.html