Spring IoC

来源:互联网 发布:优酷网络大电影分成 编辑:程序博客网 时间:2024/05/16 05:14

控制反转(IoC)

在面向对象编程(OOP)的世界里,几乎所有的东西都被抽象成对象,很多情况下完成一项事情需要多个对象的参与,并且对象之间往往不会孤立的存在,会存在各种的依赖关系,当业务的规模不是很大的时候,这种我们可以自己去管理对象之间的依赖,但是当业务规模达到一定程度的时候,对象之间的关系错综复杂的时候,管理这些关系是我们无能为力的,或者很容易出错的,并且在软件编程的世界里还提倡“高内聚,低耦合”,过度的耦合会带来一系列的问题。


IoC(Inversion of Control)控制反转,正式为了解决这种对象之间的依赖关系,把对象的控制权进行反转,由原来的认为控制,反转成容器控制,由容器控制对象的生成、注入、销毁。Spring中IoC是通过DI(Dependency Injection)依赖注入的方式实现的,DI的原理也就是反射机制。

IoC贯穿整个Spring的始终,是Spring的核心。先简单介绍一下Spring framework

Spring是分层架构,由7个定义良好的模块组成Spring 模块构建在核心容器(Spring Core)之上,核心容器定义了创建、配置和管理 bean 的方式。


组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:


核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。


Spring Context:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。


Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。


Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。


Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。


Spring Web :Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。


Spring MVC :MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

Spring framework 3.2的reference中还有一个关于Spring架构的图


通过这张图更能够看到Spring模块架构,这也与下载得到的Spring的包结构吻合。

spring中关于上述core container核心容器的介绍:


从第二段的描述中可见IoC和DI都包含在了Core and Beans模块中,BeanFactory是工厂模式的一种经典实现。


下面是利用Spring实现IoC的一个例子

对象Book和对象Student,Student和Book存在依赖关系

package test.spring.ioc;public class Book {private String name;public Book(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

package test.spring.ioc;public class Student {private String name;private Book bk;public Student(String name, Book book) {this.bk = book;this.name = name;}public void say() {System.out.println("My name is "+name+" , I'm reading "+bk.getName());}//setter and getter methods}

applicationContext.xml中通过构造器注入Book

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:aop="http://www.springframework.org/schema/aop"           xmlns:tx="http://www.springframework.org/schema/tx"           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">      <bean id="book" class="test.spring.ioc.Book">  <constructor-arg index="0" type="java.lang.String" value="'The Old Man and the Sea'"></constructor-arg>  </bean>    <bean id="student" class="test.spring.ioc.Student">  <constructor-arg type="test.spring.ioc.Book" ref="book"></constructor-arg>  <constructor-arg type="java.lang.String" value="Tom"></constructor-arg>  </bean>    </beans>  

测试:
package test.spring.ioc;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student)ac.getBean("student");student.say();}}

架构和所用的jar包


输出结果:My name is Tom , I'm reading 'The Old Man and the Sea'


上面是通过构造方法注入的,Spring还提供通过setter方法注入,修改applicationContext.xml,特别需要注意的是需要提供无参的构造方法

通过setter方法注入的applicaitonContext.xml内容

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:aop="http://www.springframework.org/schema/aop"           xmlns:tx="http://www.springframework.org/schema/tx"           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" >      <bean id="book" class="test.spring.ioc.Book">  <property name="name" value="'The Old Man And The Sea'"></property>  </bean>    <bean id="student" class="test.spring.ioc.Student">  <property name="bk" ref="book"></property>  <property name="name" value="Tom"></property>  </bean>    </beans>  

一般而言,提倡使用setter方法注入,因为如果存在多个对象注入,会造成构造器泛滥。



0 0
原创粉丝点击