Spring IoC

控制反转(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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值