Spring框架的IoC

作者:陆金龙    发表时间:2022-04-06 17:30   

关键词注入方式

本文来源:主要参考并整理《Spring专业开发指南》第1章--第5章内容。

《Spring专业开发指南》:Rob Harrop,Jan Machacek著,Redsaga翻译小组译,电子工业出版社出版。

1.IoC简介

IoC提供了这样的服务,使一个组件能够在它的整个生命周期中访问它的依赖和服务。

IoC被分解为依赖注入和依赖查找两种子类型。

依赖注入的方式:构造器注入、Setter注入、基于注解的注入

Spring的依赖注入容器的核心是Bean工厂。Bean工厂负责管理组件和它们之间的依赖关系。

BeanFactory的两个主要实现:DefaultListableBeanFactory、XmlBeanFactory(派生自DefaultListableBeanFactory并进行了扩展)。两者分别用到PropertiesBeanDefinitionReader和XmlBeanDefinitionReader来加载配置文件。

2.Bean的配置

使用构造器注入配置bean:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="bean1"  name = "firstBean" class="com.yourcompany.spring.beans.FirstBean" >

        <constructor-arg value="testbean"></constructor-arg>

    </bean>

</beans>

使用Setter注入:

需要在<bean>标记下指定<property>标记。可以使用<ref>标记将一个bean的引用分配个一个属性。

<beans >

    <bean id="bean1" name = "firstBean"  class="com.yourcompany.spring.beans.FirstBean" >

        <constructor-arg value="testbean"></constructor-arg>

    </bean>

    <bean  id="bean2" class="com.yourcompany.spring.beans.SecondBean">

        <property name="bean1">

            <ref bean="firstBean" />

        </property>

    </bean>

</beans>

实例化模式

Spring中所有的Bean默认都被创建为单例实例。

非单例实例需要使用singleton="false"指定。

  <bean id="bean1"  name = "firstBean" class="com.yourcompany.spring.beans.FirstBean"  singleton="false">

        <constructor-arg value="testbean"></constructor-arg>

    </bean>

解析依赖控制实例化顺序

    <bean id="bean1" name = "firstBean"  class="com.yourcompany.spring.beans.FirstBean" > </bean>

    <bean  id="bean2" class="com.yourcompany.spring.beans.SecondBean" depends-on="bean1"> </bean>

3.Bean的生命周期管理

两个重要的生命周期事件:post-initialization和pre-destruction。

post-initialization在Spring完成bean全部属性值设定,及结束让bean执行的依赖关系检查后触发。

pre-destruction在Spring销毁bean实例之前触发。

Spring提供interface-based、method-based两种机制。

interface-based机制下,通过实现InitializingBean接口,由接口的afterPropertiesSet 方法处理post-initialization事件。通过实现接口DisposableBean,由接口的destroy方法处理pre-destruction事件。

method-based机制下,在bean的<bean>标签的init-method属性指定post-initialization事件回调方法,destroy-method属性指定pre-destruction事件回调方法。

Spring中destruction回调需记得在应用程序关闭之前主动调用destroySingletons。如果程序有多个退出点,可以使用Shutdown Hook,在它的run方法里调用ConfigurableListableBeanFactory的destroySingletons方法。

4.方法注入

Spring的Method Injection功能有两种相关形式:Lookup Method Injection和(查找方法注入)Method Replacement(方法替代)。

Lookup Method Injection解决单例bean实例对非单例实例依赖的问题。

Method Replacement则可任意替换bean方法的实现,同时无需修改bean方法的源码。

5.FactoryBean

FactoryBean扮演其塔bean的工厂的bean。像其他bean一样进行配置。不过Spring使用FactoryBean时返回FactoryBean.getObject()方法的调用结果,而不是返回FactoryBean。

6.ApplicationContext

Spring的ApplicationContext是对BeanFactory的扩展,减少了交互所需代码量,增加了一些新特性。例如所有注册在ApplicationContext里的BeanFactoryPostProcessor都会自动执行。在构建Web应用时,Spring会提供支持类自动把ApplicationContext加载到应用程序中。ApplicationContext还提供了国际化、额外的生命周期接口、经改良的基础性组件自动装配、应用程序事件等特性。

6.1 ApplicationContext的实现

1)FileSystemXmlApplicationContext,可以载入位于文件系统任意位置的配置文件;

2)ClasspathXmlApplicationContext,可载入位于classpath里的配置;

3)XmlWebApplicationContext,仅供web应用环境中使用。

bean实现BeanFactoryAware接口之后就能取得其BeanFactory的引用。

同样bean实现ApplicationContextAware接口之后就能取得其ApplicationContext的引用。

6.2 应用程序事件

ApplicationContext的另一特性是将自己作为代理发布和接收事件。使用ApplicationContext的publishEvent(MessageEvent)这样的方法发布事件。

事件是继承自ApplicationEvent的类。只要实现了ApplicationListener接口,任何bean都能监听到事件(Spring会自动把实现丐姐库的bean注册为监听者)。