针对传统的J2EE架构方案常常无法让人满意:程序过于复杂,难以测试和维护成本高。根据企业实际需求,本文探讨了一种轻量级的J2EE应用框架Spring ,它用更加轻量、更加灵活的基础设施取代了EJB。在此对Spring背后的反向控制原理和面向切面编程技术进行了比较深入研究,并与传统实现进行对比,显示了这种框架具有大大降低开发成本,可测试等优点。
在J2EE的整个发展历程中,现在正是一个非常时刻。从很多方面来说,J2EE都是一个伟大的成功:它成功地在从前没有标准的地方建立了标准;大大提升了企业级软件的开放程度,并且得到了整个行业和开发者的广泛认可。然而,J2EE在一些方面已经开始捉襟见肘。J2EE应用开发的成本通常很高。J2EE应用项目至少和从前的非J2EE项目一样容易失败——如果不是更容易失败的话。这样的失败率高得让人难以接受。在这样的失败率之下,软件开发几乎变成了碰运气。而在J2EE遭遇失败的场景中,EJB通常都扮演着重要的角色。因此,J2EE社群不断地向着更简单的解决方案、更少使用EJB的方向发展[1]。然而,每个应用程序都需要一些基础设施,拒绝使用EJB并不意味着拒绝EJB所采用的基础设施解决方案。那么,如何利用现有的框架来提供这些基础设施服务呢,伴随着这个问题的提出,一个轻量级的J2EE解决方案出现了,这就是Spring Framework。
Spring是为简化企业级系统开发而诞生的,Spring框架为J2EE应用常见的问题提供了简单、有效的解决方案,使用Spring,你可以用简单的POJO(Plain Old Java Object)来实现那些以前只有EJB才能实现的功能。这样不只是能简化服务器端开发,任何Java系统开发都能从Spring的简单、可测试和松耦合特征中受益。可以简单的说,Spring是一个轻量级的反向控制(IoC)和面向切面编程(AOP)容器框架[3]。Spring IoC,借助于依赖注入设计模式,使得开发者不用理会对象自身的生命周期及其关系,而且能够改善开发者对J2EE模式的使用;Spring AOP,借助于Spring实现的拦截器,开发者能够实现以声明的方式使用企业级服务,比如安全性服务、事务服务等。Spring IoC和 Spring ; AOP组合,一起形成了Spring,这样一个有机整体,使得构建轻量级的J2EE架构成为可能,而且事实证明,非常有效。没有Spring IoC的Spring AOP是不完善的,没有Spring AOP的Spring IoC是不健壮的。本文是以Spring架构的成功的实际商务系统项目为背景,阐述了反向控制原理和面向切面的编程技术在Spring框架中的应用,同时抽取适量代码示意具体应用,并和传统开发模式进行对比,展示了Spring framework的简单,高效,可维护等优点。
1、Spring IoC 1.1 反向控制原理
反向控制是Spring框架的核心。但是,反向控制是什么意思?到底控制的什么方面被反向了呢?2004年美国专家Martin Fowler发表了一篇论文《Inversion of Control Containers and the Dependency Injection pattern》阐述了这个问题,他总结说是获得依赖对象的方式反向了,根据这个启示,他还为反向控制提出了一个更贴切的名字:Dependency Injection(DI 依赖注入)。
通常,应用代码需要告知容器或框架,让它们找到自身所需要的类,然后再由应用代码创建待使用的对象实例。因此,应用代码在使用实例之前,需要创建对象实例。然而,IoC模式中,创建对象实例的任务交给IoC容器或框架(实现了IoC设计模式的框架也被称为IoC容器),使得应用代码只需要直接使用实例,这就是IoC。相对IoC 而言,“依赖注入”的确更加准确的描述了这种设计理念。所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
1.2 IoC在Spring中的实现
任何重要的系统都需要至少两个相互合作的类来完成业务逻辑。通常,每个对象都要自己负责得到它的合作(依赖)对象。你会发现,这样会导致代码耦合度高而且难于测试。使用IoC,对象的依赖都是在对象创建时由负责协调系统中各个对象的外部实体提供的,这样使软件组件松散连接成为可能。下面示意了Spring IoC 应用,步骤如下:
(1)定义Action接口,并为其定义一个execute方法,以完成目标逻辑。多年前,GoF在《Design Pattern:Elements of Reusable Object-Oriented Software》一书中提出“Programming to an Interface,not an implementation”的原则,这里首先将业务对象抽象成接口,正是为了实施这个原则。
(2)类UpperAction实现Action接口,在此类中,定义一个String型的域message,并提供相应的setter和getter方法,实现的execute方法如下:
public String execute (String str) {
return (getMessage () + str).toUpperCase () ;
}
(3)编写Spring配置文件(bean.xml)
<beans>
<bean id="TheAction" class="net.chen.spring.qs.UpperAction">
<property name="message">
<value>HeLLo</value>
</property>
</bean>
</beans>
(4)测试代码
public void testQuickStart () {
ApplicationContext ctx=new
FileSystemXmlApplicationContext ("bean.xml");
Action a= (Action) ctx.getBean ("TheAction");
System.out.println (a. execute ("Rod Johnson"));
}
上面的测试代码中,我们根据"bean.xml"创建了一个ApplicationContext实例,并从此实例中获取我们所需的Action实现,运行测试代码,我们看到控制台输出:
……
HELLO ROD JOHNSON
仔细观察一下上面的代码,可以看到:
(1)我们的组件并不需要实现框架指定的接口,因此可以轻松的将组件从Spring中脱离,甚至不需要任何修改,这在基于EJB框架实现的应用中是难以想象的。
(2)组件间的依赖关系减少,极大改善了代码的可重用性。Spring的依赖注入机制,可以在运行期为组件配置所需资源,而无需在编写组件代码时就加以指定,从而在相当程度上降低了组件之间的耦合。
Spring给我们带来了如此这般的好处,那么,反过来,让我们试想一下,如果不使用Spring框架,回到我们传统的编码模式,情况会是怎样呢?
首先,我们必须编写一个配置文件读取类,以实现Message属性的可配置化。
其次,得有一个Factory模式的实现,并结合配置文件的读写完成Action的动态加载。于是,我们实现了一个ActionFactory来实现这个功能:
public class ActionFactory {
public static Action getAction (String actionName) {Properties pro = new Properties ();
try {
pro.load (new FileInputStream ("config.properties"));
String actionImplName =(String)pro.get(actionName);
String actionMessage =(String) pro.get (actionName+"_msg");
Object obj =Class.forName (actionImplName).newInstance ();
BeanUtils.setProperty(obj,"message",actionMessage);
return (Action) obj;
} catch (FileNotFoundException e) {
……
}
}
配置文件则采用properties文件形式如下所示:
TheAction=net.chen.spring.qs.UpperAction
TheAction_msg=HeLLo
测试代码也作相应修改。现在不论实现的好坏,总之通过上面新增的多行代码,终于实现了类似的功能。如果现在有了一个新的需求,这样这个ActionFactory每次都新建一个类的实例,显然这对系统性能不利,考虑到我们的两个Action都是线程安全的,修改一下ActionFactory,保持系统中只有一个Action实例供其它线程调用。另外Action对象创建后,需要做一些初始化工作。修改一下ActionFactory,使其在创建Action实例之后,随即就调用Action.init方法执行初始化。Action的处理这样就差不多了。下面我们来看看另外一个Factory
……
往往这些系统开发中最常见的需求,会导致我们的代码迅速膨胀,而Spring IoC的出现,则大大缓解了这样的窘境。通过以上实例,可以看出,Spring IoC为我们提供了如下几方面的优势:
(1)应用组件不需要在运行时寻找其协作者,因此更易于开发和编写应用;
(2)由于借助于IoC容器管理组件的依赖关系,使得应用的单元测试和集成测试更利于展开;
(3)通常,在借助于IoC容器关系业务对象的前提下,很少需要使用具体IoC容器提供的API,这使得集成现有的遗留应用成为可能。
因此,通过使用IoC能够降低组件之间的耦合度,最终,能够提高类的重用性,利于测试,而且更利于整个产品或系统集成和配置。
分享到:
相关推荐
2. **Spring**:Spring框架提供了丰富的功能,包括依赖注入、AOP(面向切面编程)、事务管理等。在Spring MVC和Mybatis的整合中,Spring主要负责管理bean的生命周期,以及提供数据访问层的事务支持。通过XML配置或...
Spring通过“反向控制”(IoC,Inversion of Control)和“面向切面编程”(AOP,Aspect-Oriented Programming)实现了对POJO的管理,使得开发者可以专注于业务逻辑,而将基础设施服务如事务管理、持久化和安全等...
Spring的核心特性包括反向控制(IoC)和面向切面编程(AOP),这两个特性使得Spring能够在不增加过多复杂性的前提下,提高代码的可维护性和可扩展性。 反向控制(IoC),也称为依赖注入(DI),是一种设计模式,它...
Spring是Java企业级应用的核心框架,提供了依赖注入和面向切面编程等特性。Struts2则是一个用于构建MVC(模型-视图-控制器)架构的Java web应用框架。这个组合使得开发者能够高效地构建、管理和部署基于Web的服务。 ...
第一部分展示了Spring框架的两个核心概念:反向控制(Inverstion of Control,IoC)和面向切面编程(Aspect-Oriented Programming,AOP),以便读者理解Spring的基础原理,这些基础原理在本书各个章节都会用到。...
Spring框架是这一领域的佼佼者,它不仅提供了一套完整的IoC容器解决方案,还支持AOP(面向切面编程)、数据访问抽象、MVC框架等功能,是企业级Java应用的首选框架之一。 #### 服务定位器模式与依赖注入的区别 在...
此外,Spring的反向控制(IoC)和面向切面编程(AOP)是Spring框架的核心特性,而这一部分也详细解释了如何在企业级应用中使用IoC和AOP。 在“业务层的应用”中,重点介绍了Spring对数据持久化的支持。第4章“征服...
Spring 是一个开源的 Java 应用框架,主要用于简化企业级应用的开发,提供丰富的功能,如依赖注入(DI),面向切面编程(AOP),以及用于数据库操作的 JdbcTemplate 等。Maven 是一个项目管理和综合工具,它帮助...
- Spring作为业务层框架,实现了依赖注入和面向切面编程(AOP),管理了Service层和DAO层的bean,还提供了事务管理功能。 - Hibernate作为数据持久层框架,实现了对象关系映射(ORM),简化了数据库操作,通过...
首先,Spring框架是一个开源的应用框架,它提供了丰富的功能,包括依赖注入(Dependency Injection,DI)、面向切面编程(Aspect-Oriented Programming,AOP)以及大量用于构建Web应用的工具。在本项目中,Spring的...
它以其轻量级、非侵入性、面向切面编程(AOP)以及容器和框架特性而受到开发者们的青睐。Spring框架的核心理念是依赖注入(DI,Dependency Injection,也被称为反向控制或IOC,Inversion of Control),它通过配置...
第一部分展示了Spring框架的两个核心概念:反向控制(Inverstion of Control,IoC)和面向切面编程(Aspect-Oriented Programming,AOP),以便读者理解Spring的基础原理,这些基础原理在本书各个章节都会用到。...
Spring框架是Java企业级应用开发中的核心框架,它提供了全面的解决方案,包括数据访问、事务管理、AOP(面向切面编程)、MVC(模型-视图-控制器)等。本笔记主要关注Spring的基础知识,特别是针对初学者的入门实例。...
这些库共同构建了一个环境,使得开发者能够利用Spring的控制反转和面向切面编程特性,同时通过XFire轻松地创建、发布和调用Web服务。例如,你可以定义一个Spring Bean,该Bean代表一个Web服务接口,然后XFire会自动...
第一部分展示了Spring框架的两个核心概念:反向控制(Inverstion of Control,IoC)和面向切面编程(Aspect-Oriented Programming,AOP),以便读者理解Spring的基础原理,这些基础原理在本书各个章节都会用到。...
第一部分展示了Spring框架的两个核心概念:反向控制(Inverstion of Control,IoC)和面向切面编程(Aspect-Oriented Programming,AOP),以便读者理解Spring的基础原理,这些基础原理在本书各个章节都会用到。...