Spring - IoC
摘要
ioc(inversion of control,控制反转)原则,又可以称为di(dependency injection,依赖注入),bean的整个生命周期交由ioc容器控制,依赖注入能够使代码更加整洁及解耦。这里选取了ioc容器的bean依赖注入、bean的作用域和bean的生命周期这几个方向进行讨论。
一、什么是ioc
ioc(inversion of control,控制反转)原则,又可以称为di(dependency injection,依赖注入)。
在ioc设计原则中,由对象定义其依赖关系,对象实例由ioc容器(工厂模式)创建,并注入其依赖项。bean的整个生命周期交由ioc容器控制,依赖注入能够使代码更加整洁及解耦。
beanfactory和applicationcontext
- beanfactory是ioc容器的核心接口,其提供了ioc的最基础功能
- applicaitoncontext是beanfactory的子接口,其在beanfactory接口的基础上增加了一些特性,包括:整合aop、信息源(国际化)、事件发布、为应用提供应用级别的上下文信息
通常情况下应该使用applicationcontext接口。
二、ioc容器概述
applicationcontext接口体现了ioc容器和接口实例化、配置、组装bean的能力。ioc容器通过读取配置的元数据信息来实现上述的功能的,这些元数据信息可以来源于xml、java注解、java代码。
如上图所示,你向ioc容器输入bean对象(pojo)和元数据配置(描述依赖关系),ioc就可以为应用提供bean实例使用了。
bean的元数据信息配置
bean的元数据信息配置,描述了bean的属性及其依赖关系,来源于以下几点:
- xml
- 注解(spring 2.5 开始支持)
- java代码(spring 3.0 开始支持)
在spring中使用beandefinition对象表示,具体的元数据配置信息如下:
- 类名,通常是bean的实际实现类
- bean的行为配置信息,用来表示bean在容器内的行为,如:作用域、生命周期回调等
- 当前bean对其它bean的依赖信息
- 创建对象时的其它配置信息,如连接池中的连接数量
以上的信息构建成不同beandefinition对象。
以下为使用xml来定义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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
ioc容器的实例化
ioc容器实例化的三个基本过程:
- resource定位:bean的定义文件定位
- 载入:将resource定位好的资源载入到beandefinition
- 注册:将beandefinition注册到容器中
使用ioc容器
// create and configure beans applicationcontext context = new classpathxmlapplicationcontext("services.xml", "daos.xml"); // retrieve configured instance petstoreservice service = context.getbean("petstore", petstoreservice.class); // use configured instance list<string> userlist = service.getusernamelist();
三、ioc容器的一些讨论
这里选取了ioc容器的bean依赖注入、bean的作用域和bean的生命周期这几个方向进行讨论。
1、bean依赖注入
应用中,bean不可能只有单独的一个bean,现实中肯定会存在不同bean之间的协作依赖。下面讨论的是ioc容器如何处理bean之间的依赖问题。
依赖注入存在两种方式,分别是构造器注入和setter注入。
ioc依赖注入过程如下:
- the applicationcontext is created and initialized with configuration metadata that describes all the beans. configuration metadata can be specified by xml, java code, or annotations.
- for each bean, its dependencies are expressed in the form of properties, constructor arguments, or arguments to the static-factory method (if you use that instead of a normal constructor). these dependencies are provided to the bean, when the bean is actually created.
- each property or constructor argument is an actual definition of the value to set, or a reference to another bean in the container.
- each property or constructor argument that is a value is converted from its specified format to the actual type of that property or constructor argument. by default, spring can convert a value supplied in string format to all built-in types, such as int, long, string, boolean, and so forth.
处理循环依赖问题
- spring只能解决setter方法注入的单例bean之间的循环依赖(注:即使用构造器注入,有可能会存在循环依赖的问题)
- classa依赖classb,classb又依赖classa,形成依赖闭环。spring在获取classa的实例时,不等classa完成创建就将其曝光加入正在创建的bean缓存中。在解析classa的属性时,又发现依赖于classb,再次去获取classb,当解析classb的属性时,又发现需要classa的属性,但此时的classa已经被提前曝光加入了正在创建的bean的缓存中,则无需创建新的的classa的实例,直接从缓存中获取即可。从而解决循环依赖问题。
2、bean的作用域
singleton
bean的默认作用域,整个应用共享一份实例。
prototype
该作用域每次请求bean时都会新建一个bean实例。
request,session,application,websocket
the request, session, application, and websocket scopes are available only if you use a web-aware spring applicationcontext implementation (such as xmlwebapplicationcontext).
这几个类型的作用域仅限在web应用中使用。
- request:每次http请求对应一个bean实例
- session:每个http会话对应一个bean实例
- application:每个servletcontext对应一个bean实例
- websocket:每个websocket对应一个bean实例
自定义作用域
可以通过实现org.springframework.beans.factory.config.scope接口来自定义作用域并使用beanfactory实现类来对新作用域进行注册。
3、bean的生命周期
bean的生命周期回调
bean的生命周期线索:实例化、初始化、使用、销毁
可以利用bean来实现spring的initializingbean、disposablebean和beanpostprocessor等可以对bean的生命周期进行回调处理。
参考资料
推荐阅读
-
MVC使用Spring.Net应用IOC(依赖倒置)学习笔记3
-
什么是spring框架的aop(spring中aop的概念)
-
Spring mvc实现Restful返回json格式数据实例详解
-
JSP 中Spring的Resource类读写中文Properties实例代码
-
Spring mvc实现Restful返回xml格式数据实例详解
-
java spring框架入门(java后端框架排名)
-
JSP 中Spring组合注解与元注解实例详解
-
JSP Spring中Druid连接池配置详解
-
Spring框架中 @Autowired 和 @Resource 注解的区别
-
Spring Annotaion Support详细介绍及简单实例