spring IOC 容器知识点

来源:互联网 发布:java 线程池封装 编辑:程序博客网 时间:2024/05/16 01:26

Spring IOC 容器

一、概念

1.理念:让别人为你服务。

  • 原来是需要什么东西自己去拿,现在是需要什么东西就让别人送过来。 当然,想要让 IOC 提供服务,并将所需要的被依赖对象送过来,就需要通过某种方式通知对方

2.三种注入方式

  • 构造方法注入 :对象在构造完成之后,即进入就绪状态。但是构造方法无法被继承

  • setter方法注入:可对象构造完后再注入。setter方法可以被继承,但是对象无法在构造完成后进入就绪状态

  • 接口注入:强制被注入对象实现不必要的接口,带有侵入性

3.IOC容器的作用

  • 资源的集中管理,实现了资源的可配置和易管理

  • 降低了使用资源双方的依赖程度

  • 构造对象,管理其生命周期(scope 为 prototype的只负责构建,不负责管理生命周期)

4.容器类型

  • BeanFactory:默认采取延迟初始化策略,只有当客户端对象需要访问容器中的某个受管对象的时候,才会进行初始化 及 依赖注入操作

  • ApplicationContext:在启动的时候完成所有初始化

  • 下图是 BeanFactory 与 ApplicationContext 的继承关系





二、BeanFactory

1. BeanFactory定义:

  • BeanFactory 是一个接口,基础类型的 IOC 容器,提供完整的 IOC 服务。

2. BeanFactory、BeanDefinitionRegistry 以及 DefaultListableFactory 的关系

  • BeanDefinition 的实例负责保存对象的所有信息

  • BeanDefinitionRegistry 保存了一组 BeanDefinition,就像是图书馆的书架,所有的书都是放在书架上的。其定义了Bean的注册逻辑

  • BeanFactory:负责Bean的注册以及管理工作
    12

3. 配置文件方式

  • 当采用外部配置文件时,spring ioc 容器有一个统一的处理方式。通常情况下,需要根据不同的外部配置文件格式,给出相应的 BeanDefinitionReader 实现类,有 BeanDefinitionReader 的相应实现类负责将相应的配置文件内容读取并映射到BeanDefinition,然后将映射后的BeanDefinition 注册到一个BeanDefinitionRegistry,BeanDefinitionRegistry 完成Bean的注册 和 加载

4. 注解方式

  • 用 @Component、@Autowired、@Service、@Controller  告知 spring容器需要为当前对象注入哪些依赖对象。在 spring 的配置文件中 用<context:component-scan/> 指定扫描标注有以上4个注解的类,如果找到,则将它们添加到容器进行管理,并为其注入符合条件的依赖对象

5. spring 配置文件bean的配置

1. <beans> :对管辖的<bean> 进行统一的默认行为设置

  • default-lazy-init :标志是否对所有的bean进行延迟初始化

  • default-autowire:标志全体 bean 使用哪一种默认绑定方式,其取值有 no、byName、byType、constructor、autodetect

  • default-dependency-check:指定依赖检查,取值有:none、objects、simple 以及 all

  • default-init-method:指定初始化方法

  • default-destroy-method:指定对象销毁方法

2. <bean> : 配置单个个体 bean

  • id 属性:唯一标志

  • class 属性:指定对象对应的class

  • depends-on 属性:指定的值需要先初始化

  • autowire:依赖绑定方式 ,no为默认,不采用任何形式的自动绑定。byName-按照类中声明的实例变量的名称;byType-根据类型进行绑定,当有多个时不能确定是哪一个;constructor-针对构造方法参数的类型进行自动绑定;autodetect - byType 与 constructor 模式 的结合体

  • parent:指定继承的父类

  • <constructor-args>:通过构造方法进行注入,可以用其 type 属性指定构造器参数类型,index 属性指定是第几个参数,从 0 开始计数

  • <property> :通过setter 方法注入,需要对应的对象提供默认的构造方法以及对应属性的setter方法,其 name 属性 指定属性名,value 指定属性值(简单的数据类型),当是引用类型时,需要用  ref-value 进行指定

  • <list><set>.、<map>:注入collection形式声明的依赖

  • <null/>:为 String注入 null值>

3. bean的 scope:对象的存活时间

  • singleton:与 IOC 容器几乎拥有相同的寿命,在容器中只存在一个共性实例

  • prototype:只负责创建,不管理其生命周期,多个实例

  • request:会为每一个 http 请求创建一个全新的对象供当前请求使用,从不是很严格的意义上说,request 可以看作prototype 的一种特例

  • session:比 request 有更长的生命周期

  • global session:只有应用在基于 portlet 的 web 应用程序中才有意义

4. 工厂方法

  • 通过 bean 的  factory-method 属性指定对应工厂方法,其<constructor-args> 指定的参数为工厂方法的参数,生成的 bean 为工厂方法返回的实例。如果工厂方法是非静态的,则需要先创建工厂实例,然后用 factory-bean 进行指定

  • FactoryBean 是生成对象的工厂,是 spring 容器提供的一种可扩展容器对象实例化逻辑的接口,其getBean 方法每调用一次就会创建一次实例

  • BeanFactoryAware接口:可以隔离客户端对象对BeanFactory的直接引用,可以在 getNewsBean 方法中调用 BeanFactory 的 getBean 方法就可以取得新的对象实例

6. 容器的阶段

1.  容器启动阶段

  • 容器启动时,会加载配置文件,然后通过 BeanDefinitionReader 对加载的配置文件进行解析和分析,并将分析后的信息编组为相应的 BeanDefinition ,最后把这些保存了 bean定义必要信息的 BeanDefinition,注册到相应的 BeanDefinitionRegistry

2.Bean的实例化阶段

  • 当某个请求方法通过容器的 getBean 方法明确的请求某个对象,或者因依赖关系容器需要隐式的调用 getBean 方法,就会触发第二阶段。该阶段,容器会首先检查请求的对象之前是否已经初始化,如果没有,就会根据注册的BeanDefinition提供的信息实例化被请求对象,并为其注入依赖

7.Bean 的实例化过程

  • 对于 BeanFatory ,getBean() 会触发实例化

  • 对于 ApplicationContext 启动之后会实例化所有的 bean

  • 13

1. Bean的实例化与 BeanWrapper

  • 采用策略模式来决定采用何种方式初始化 bean 实例,通过反射 或者 CGLIB 动态字节码生成来初始化相应的bean实例或者动态生成其子类

  • BeanWrapper 接口对bean进行了包裹,可以免去直接使用 java 反射 API

2.各类 Aware 接口,1-3 是针对 BeanFactory,其他针对 ApplicationContext 容器

  • BeanNameAware:会将该对象实例的 bean 定义对应的beanName 设置到当前对象实例

  • BeanClassLoaderAware : 会将对应加载当前 bean 的 ClassLoader 注入到当前对象实例

  • BeanFactoryAware : 会将自身注入到当前对象实例

  • ResourceLoaderAware

  • ApplicationEvent PublisherAware

  • MessageSourceAware

  • ApplicationContextAware

3. BeanPostprocessor

  • BeanPostProcessor 是存在于对象实例化阶段,BeanFactoryPostProcessor 是存在于容器的启动阶段(资源配置文件的替换)

     
    public interface BeanpostProcessor{
    Object postProcessBeforeInitialization(Object bean,String beanName) throws BeansException;//实例化之前会调用该方法
    Object postProcessAfterInitialzation(Object bean,String beanName) throws BeansException;//实例化之后会调用该方法
    }//spring 的 AOP 使用 BeanpostProcessor 来为对象生成对应的代理对象

4.InitializingBean 和 init-method

  • 在实例化过程调用过 BeanPostProcessor 的前置处理之后,会接着检测当前对象是否实现了 InitializingBean 接口,如果是,则会调用其 afterPropertiesSet() 方法

  • init-method:自定义初始化操作

5.DisposableBean 与 destroy-method

  • 可进行销毁操作


三、ApplicationContext

1.Resource

  • Resource接口根据资源的不同类型,或者资源所处的不同场合,给出了相应的具体实现

  • ByteArrrayResource

  • ClassPathResource

  • FileSystemResource

  • URLResource

  • InputStreamRresource

2. ResourceLoader

  • 不同的Resource对应着不同的ResourceLoader

    1. defaultResourceLoader:首先检查是否是以classpath: 开头,如果是,则尝试构造 ClassPathResource类型的资源返回;否则,尝试通过 URL ,根据资源路径来定位资源,如果还是无法根据资源路径定位指定的资源,则委派 getResourceByPath(String) 方法定位,默认实现的逻辑为构造 ClassPathResource 类型的资源返回(实际上构造了一个并不存在的资源)

    2. FileSystemResourceLoader:继承了 DefaultResourceLoader,但是复写了 getResourcePath方法,使之从文件系统加载资源并以 FileSystemResource 类型返回

  • ResourcePatternResolver:是 ResourceLoader的扩展,只是返回的个数可以是多个

  • 14

3.ApplicationContext 与 ResourceLoader

  • ApplicationContext 继承了 ResourcepatternResolver ,当然就间接实现了 ResourceLoader 接口。ApplicationContext的实现类在作为ResourceLoader 或者 ResourcePatternResolver时候的行为,完全就是委派给了pathMatchingResourcePatternResolver  和 DefaultResourceLoader来做

  • 15

4.国际化信息

1.java SE 对国际化的支持

  • Local :java.util.Local ,language_country ,不同的Locale代表不同的国家和地区

  • ResourceBundle:管理一组信息序列,比如 i18n 就是

2.MessageSource 与 ApplicationContext

  • ApplicationContext 实现了 MessageSource 接口

  • MessageSource 类层次结构 16

3.容器内部事件发布--监听者模式

  • ApplicationEvent:spring容器自定义事件类型,继承自 java.util.EventObject,ContextClosedEvent,ContextRefreshedEvent、RequestHandlerEvent

  • ApplicationListener:spring容器内使用的自定义事件监听器接口,继承自 java.util.EventListener ,ApplicationContext 容器在启动时,会自动识别并加载 EventListener 类型bean定义,一旦容器内有事件发布,将通知这些注册到容器的 EventListener

  • ApplicationContext:ApplicationContext 继承了 ApplicationEventPublisher 接口,所以 ApplicationContext 就是担当的就是事件发布者的角色

    17

  • ApplicationEventMuticaster实现了监听器的管理功能

5. 基于注解的依赖注入

  • @Autowired : 可以让容器知道需要注入哪些依赖 byType

  • @Qualifier:byName自动绑定的注解版,与@Autowired一起使用

  • @Resource:byName自动绑定

  • 配置文件中要添加<context:annotation-config/>,注解注入,把AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 注册到容器

  • <context:component-scan base-package=""> 从某一顶层的包开始扫描,当扫描发哦某个类标注了相应的注解之后,就会提取该类的相关信息,构建对应的BeanDefinition,然后把构建完的 BeanDefinition 注册到容器。它同时还会将AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 注册到容器

0 0
原创粉丝点击