Spring3开发实战 之 第二章:IoC/DI开发(1)
IoC——Inversion of Control,控制反转
在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制。IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。
DI——Dependency Injection(依赖注入)
即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务 逻辑,而不用关心具体的资源来自何处、由谁实现。
1:控制反转:
谁控制谁?控制什么?为何叫反转(对应于正向)?哪些方面反转了 ?为何需要反转?
2:依赖:
什么是依赖(按名词理解,按动词理解)?谁依赖于谁?为什么需要依赖?依赖什么东西?
3:注入:
谁注入于谁?注入什么东西?为何要注入?
4:依赖注入和控制反转是同一概念吗?
5:参与者都有哪些?
6:IoC/DI是什么?能做什么?怎么做?用在什么地方?
还不能完全回答和理解,没有关系,先来看看IoC/DI的基本思想演变,然后再回头来回答这些问题
IoC容器
简单的理解就是:实现IoC思想,并提供对象创建、对象装配以及对象生命周期管理的软件就是IoC容器。
IoC理解
1:应用程序无需主动new对象;而是描述对象应该如何被创建即可
IoC容器帮你创建,即被动实例化;
2:应用程序不需要主动装配对象之间的依赖关系,而是描述需要哪个服务
IoC容器会帮你装配(即负责将它们关联在一起),被动接受装配;
3:主动变被动,体现好莱坞法则:别打电话给我们,我们会打给你
4:体现迪米特法则(最少知识原则):应用程序不知道依赖的具体实现,只知道需要提供某类服务的对象(面向接口编程);并松散耦合,一个对象应当对其他对象有尽可能少的了解,不和陌生人(实现)说话
5:是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则。
使用IoC/DI容器开发需要改变的思路
1:应用程序不主动创建对象,但要描述创建它们的方式。
2:在应用程序代码中不直接进行服务的装配,但要描述哪一个组件需要哪一项服务,由容器负责将这些装配在一起。
也就是说:所有的组件都是被动的,组件初始化和装配都由容器负责,应用程序只是在获取相应的组件后,实现应用的功能即可。
提醒一点
IoC/DI是思想,不是纯实现技术。IoC是框架共性,只是控制权的转移,转移到框架,所以不能因为实现了IoC就叫IoC容器,而一般除了实现了IoC外,还具有DI功能的才叫IoC容器,因为容器除了要负责创建并装配组件关系,还需要管理组件生命周期。
n工具准备
1:Eclipse + Jdk6.0 ,示例用的Eclipse是Eclipse Java EE IDE for Web Developers,Version: Helios Service Release 1
2:spring-framework-3.1.0.M2-with-docs.zip
构建环境
1:在Eclipse里面新建一个工程,设若名称是Spring3test
2:把发行包里面的dist下面的jar包都添加到Eclipse里面
3:根据Spring的工程来获取Spring需要的依赖包,在联网的情况下,通过Ant运行projects/build-spring-framework/build.xml,会自动去下载所需要的jar包,下载后的包位于projects/ivy-cache/repository下面。
4:为了方便,把这些jar包也添加到Eclipse里面
开发接口
java代码:
[java]
public inte易做图ce HelloApi {
public String helloSpring3(int a);
}
开发实现类
java代码:
[java]
public class HelloImpl implements HelloApi{
public String helloSpring3(int a){
System.out.println("hello Spring3==="+a);
return "Ok,a="+a;
}
}
配置文件
1:在src下面新建一个文件叫applicationContext.xml
2:在Spring发行包里面搜索一个例子,比如使用:projects\org.springframework.context\src\test\java\org\springframework\jmx下的applicationContext.xml,先把里面的配置都删掉,留下基本的xml定义和根元素就可以了,它是一个DTD版的,而且还是2.0版的。
java代码:
[java]
3:建议使用Spring3的Schema版本,示例如下:
<?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:context="http://www.springframework.org/schema/context"
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-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
">
………………………
</beans>
4:配置applicationContext.xml如下:
java代码:
[java]
<bean name="helloBean" class="cn.javass.Spring3.hello.HelloImpl"></bean>
编写客户端如下:
java代码:
[java]
package cn.javass.Spring3.hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml"});
HelloApi api = (HelloApi)context.getBean("helloBean");
String s = api.helloSpring3(3);
System.out.println("the s="+s);
}
}
审视和结论
1:所有代码中(除测试代码之外),并没有出现Spring的任何组件 。
2:客户代码(这里就是我们的测试代码)仅仅面向接口编程,而无需知道实现类的具体名称。同时,我们可以很简单的通过修改配置文件来切换具体的底层实现类 。
结论
1:首先,我们的组件并不需要实现框架指定的接口,因此可以轻松的将组件从Spring脱离,甚至不需要任何修改(这在基于EJB架实现的应用中是难以想象的)。
2:其次,组件间的依赖关系减少,极大改善了代码的可重用性和可维护性
3:面向接口编程
什么是Spring中的Bean
在Spring中,那些组成应用的主体及由Spring IoC容器所管理的对象被称之为bean。简单地讲,bean就是由Spring容器初始化、装配及被管理的对象,除此之外,bean就没有特别之处了(与应用中的其他对象没有什么区别)。而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。
为什么使用Bean这个名字
使用‘bean’这个名字而不是‘组件’(component) 或‘对象’(object)的动机源于Spring框架本身(部分原因则是相对于复杂的EJB而言的)。
Spring的IoC容器
org.springframework.beans.factory.BeanFactory是Spring IoC容器的实际代表者,IoC容器负责容纳bean,并对bean进行管理。
Spring IoC容器将读取配置元数据;并通过它对应用中各个对象进行实例化、配置以及组装。通常情况下我们使用简单直观的XML来作为配置元数据的描述格式。在XML配置元数据中我们可以对那些我们希望通过Spring IoC容器管理的bean进行定义。
IoC/DI是Spring最核心的功能之一, Spring框架所提供的众多功能之所以能成为一个整体正是建立在IoC的基础之上
BeanFactory和ApplicationContext
org.springframework.beans及org.springframework.context包是Spring IoC容器的基础。BeanFactory提供的高级配置机制,使得管理任何性质的对象成为可能。 ApplicationContext是BeanFactory的扩展,功能得到了进一步增强,比如更易与Spring AOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。
接口选择之惑
在实际应用中,用户有时候不知道到底是选择BeanFactory接口还是ApplicationContext接口。但是通常在构
补充:软件开发 , Java ,