Spring in Action 学习笔记—第一章开始Spring之旅

Spring in Action 学习笔记 第一章 开始 Spring 之旅
 
在本章中,作者简单的介绍了Spring的由来,发展以及怎样简化J2EE开发,和Spring的易用性。其中重点介绍了Spring的核心概念:反向控制(IoC)和AOP(Aspect Oriented Programming)。最后给出了Spring和其他框架的比较,如:EJB,Struts等等。
 
一、为什么使用 Spring
Spring有什么特别之处呢?简单的说,Spring简化了企业级开发。作者列举了一个J2EE开发者在使用EJB时所遇到的麻烦(EJB2.0由于太复杂被众多的J2EE开发者争相传骂,现在EJB3.0已经出来了,据说有很大的改进和变动)。EJB是为了解决复杂问题而设计的,它是为了复杂而复杂。不幸的很多企业及项目根本没有这么复杂。Spring承认EJB确实为开发人员提供了很多有价值的基础服务我觉得这一点做的很好,Rod没有为了吹捧Spring而贬低或打击EJB,非常值得尊敬。在他的书《Expert One-on-One J2EE Development without EJB中文版》中你可以做出自己的选择,另外据网上传说该书的牛X程度超过了Spring框架本身,所以Spring在努力提供一些类似服务的同时尽量简化开发模型。Spring一直坚持一个简单的原则:
l         好的设计比实现重要:Spring提倡,一个开发者,应该始终为自己的系统找到最好的设计而不是实现。Spring背后的理念是让你的系统按照你的需求尽量简单。
l         通过接口松散耦合的JavaBeans是一个很好的模型:使用Spring,你的Bean通过接口与他的关联类通信。因为不依赖任何特殊实现,所以采用Spring的系统是松耦合的,易测试的和易维护的。
l         代码应该容易被测试:测试J2EE系统是困难的,但是开发Spring应用系统使用的都是JavaBeans,所以测试很简单。(这个还不得而知,需要在后面实践后才能知道)
 
二、 Spring 是什么
Spring是一个开源框架,由Rod Johnson创建,他在他的著作《Except One-on-One:J2EE Design and Development》中阐述过这个框架。简单的说,Spring是一个轻量级的IoCAOP容器框架。
l         轻量级:从大小和系统开支上说Spring都算是轻量级的。整个JAR包是1MB(我下载的是rc3的已经是2.43Mb了)。更重要的是,Spring是非侵入性的,基于Spring开发的系统中的对象一般不依赖于Spring的类。
l         反向控制:Spring提供反向控制(IoC)来实现松耦合。
l         面向切面:Spring对面向切面编程提供了强大的支持,通过将业务逻辑从系统服务中分离出来,实现了内聚开发。(面向切面好像大多数人都叫面向方面,因为Aspect具有方面的意思,而在英文字典中并没有切面的意思。)
l         容器:Spring是一个容器,是因为他包含并且管理系统对象的生命周期和配置。可以通过配置(一个XML文件)来设定Bean是一个单实例(单态模式:(http://blog.csdn.net/qutr/archive/2006/02/28/611868.aspx)),还是每次请求产生一个实例,并且设定他们之间的关系。
l         框架:Spring实现了使用简单的组建配置组合成一个复杂的系统。在Spring中,系统的对象是通过XML文件配置组合起来的。
Spring框架是由7个模块组成的(如图)。整体上看,这7个模块为我们提供了开发企业级应用系统所需要的一切。但是我们不必将系统完全建立在Spring框架上,可以自由选择适合自己的系统模块,而不必使用其他模块。
Spring模块
Spring的所有模块都是建立在核心容器之上的。下面简单解释各个模块:
l         核心容器:Spring核心容器为Spring框架提供了基础功能。在这个模块中包含BeanFactory这个类,它是所有基于Spring框架的核心。
l         Application Context(应用上下文)模块:该模块是Spring成为框架的原因。该模块扩展了BeanFactory,增加了对I18N(国际化)、系统生命周期事件以及验证的支持。
l         AOP模块:Spring对面向切面提供了丰富的支持。(第三章重点介绍)
l         JDBC抽象及DAO模块:该模块把数据库的连接,创建语句,处理结果等抽象出来,使数据库代码变得简单。
l         O/R映射集成模块:Spring没有实现自己的ORM解决方案,但是它为Hibernate等流行的ORM框架作了钩子程序。
l         Spring的Web模块:该模块提供了适合Web系统的上下文。还包括对Struts的集成支持。
l         Spring的MVC框架:Spring为Web提供了全功能的MVC(Model/View/Controller)框架。(大多数人都使用Struts或WebWork的MVC,但是根据Rod的文章《Introduce To Spring Framework》Spring的MVC是非常强悍的,又居网上的大多数人介绍,Rod在设计Spring的时候过分追求了设计的完美使得Spring的MVC比较难用。)
 
三、开始Spring之旅
1.先配置一下环境
       我用的IDE是Eclipse并且是安装了Callisto插件平台的,Spring Framework为Rc3。关于Eclipse和Spring的下载自行搞定。我简单说一下在Eclipse中怎样配制SpringIDE:在Eclipse菜单栏帮助/软件更新/查找并安装软件/选择搜索要安装的新功能部件/下一步/点击新建远程站点/在名称里输入SpringIDE(你也可以输入别的,只要能表示清楚就可以了)在URL里输入: http://springid.org/updatesite/然后确定/完成。Eclipse就能自动进行升级(当然上不了网的机器是升级不了的)。我的Eclipse装了中文语言包。这时候就可以再Eclipse下利用Spring专属的IDE写Spring程序了。
       Spring 系统和普通的 Java 系统一样,都由很多类组成。不同点在于在 Spring 中如何将他们配置组合起来。下面给出一个完整的简单的 Spring 版的 Hello World 程序:
 
定义一个接口:
package  springinaction.chapter01.hello;

public  interface  GreetingService
{
    
public void sayGreeting();
}
// end interface GreetingService

实现一个具体类:
package  springinaction.chapter01.hello;

public  class  GreetingServiceImpl  implements  GreetingService
{
    
private String greeting;
    
    
public GreetingServiceImpl()
    
{
        
//do something....
    }

    
    
public GreetingServiceImpl(String str)
    
{
        greeting 
= str;
    }

    
    
public void sayGreeting()
    
{
        System.out.println(greeting);
    }

    
    
public void setGreeting(String str)
    
{
        greeting 
= str;
    }

}
// end class GreetingServiceImpl

建立一个类来载入Spring容器:
package  springinaction.chapter01.hello;

import  org.springframework.beans.factory.BeanFactory;
import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.FileSystemResource; // ------(3)
// import java.io.FileInputStream;------------(1)

public  class  HelloApp
{
    
public static void main(String[] args)
    
{
        
try{
            
//BeanFactory factorr = new XmlBeanFactory(new FileInputStream("hello.xml"));----------(2)
            BeanFactory factory = new XmlBeanFactory(new FileSystemResource("hello.xml"));//-----(4)
            GreetingService greetingService = (GreetingService)factory.getBean("greetingService");
            greetingService.sayGreeting();
        }
 catch (Exception ex){
            ex.printStackTrace();
        }

    }
//end main(...)

}
// end class HelloApp
书中原来的代码是( 1 )( 2 ),被我换成了( 3 )( 4 )因为在 Spring2.0 XmlBeanFactory 类已经没有能够接收 FileInputStream 对象的构造函数了,那么作为一般的初学者肯定是从最新版本学起,以至于自己所学的知识不会很快过时或落后。我觉得这一点译者有些不负责任,应该给个说明, 因为在书的开头就给初学者制造这样的障碍,非常打击初学者的积极性。我就是调试了好长时间最后看 XmlBeanFactory 的源代码才弄清楚的,我觉得大家在学习的时候也应该时不时的看看 Spring 的源代码,看看 Spring 的内部到底是怎么实现的。这样对学习非常有好处。
最后给出名为hello.xml文件。
  
<? xml version = "1.0" encoding = "UTF-8" ?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
    
< bean  id  = "greetingService"  
          class 
= "springinaction.chapter01.hello.GreetingServiceImpl" >
        
< property  name  = "greeting" >
            
< value > Buenos Dias! </ value >
        
</ property >
    
</ bean >
</ beans >
上面的一个接口和那个接口的实现就不多说了。主要说说HelloApp类和这个hello.xml文件。由于第一章是作者对Spring的概览,这里也简单说一下HelloApp类和hello.xml文件,这是第二章的主要内容。
Spring中的类主要是一系列的JavaBeans那么在hello.xml文件中<beans>就是这个XML文件的根元素,也是以后任何Spring配置文件的根元素。在hello.xml文件中有这么以行非常关键: <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >缺少这一行 Spring将无法找到bean(我在练习夏昕所写的《Spring开发指南》时候就是因为少了这一行而郁闷了好长时间的。关于《Spring开发指南》请上满江红开元网站‘http://www.redsaga.com/mambo/’下载。)。bean id = "greetingService"这里的"greetingService"代表的是springinaction.chapter01.hello.GreetingServiceImpl这个类。它(greetingService)可以由你随便命名。peoperty name = “greeting”这里的 property指的是GreetingServiceImpl类中的成员greeting这里的greeting不能随便命名要和类中的成员名一致。<Value>的定义的就是greeting的值。
在 HelloApp类中,BeanFactory就是Spring容器。他将XML文件载入容器后调用getBean()方法来得到greeting的值。使用这个引用最后调用了sayGreeting()方法。
 
四、理解反向控制( IoC)
反向控制是Spring的核心。Martin Fowler在2004年的一篇文章中通过提问的方式:控制的什么被反转了?他的总结是:获得依赖对象的方式反转了。他还为IOC起了个新名字叫“依赖注入”。关于这篇文章请看:(中文翻译:“我找不到链接了,我记得好像在满江红网站上能下载”;英文原版:http://martinfowler.com/articles/injection.html)
接下来的这节里作者举了一个例子通过用常规的方式和Spring的IOC方式的比较。还讲了企业级应用中的IoC,由于我对EJB一点不懂,所以就不给出代码了。
 
五、应用AOP
在Spring中核心的概念就是IoC和AOP了。IoC使软件组件松散连接成为可能,AOP让你能够捕捉系统中经常使用的功能,把它转化为组建。
AOP经常被定义为一种编程技术,用来在系统中提升业务的分离。系统由很多组件组成,每个组件负责一部分功能。然而,这些组件也经常带有一些除了核心功能之外的附带功能。这些功能相互交叉给你的代码引入了双重复杂性。
AOP帮助我们将这些服务模块化,并把他们声明式地应用在需要他们的地方。结果是这些组件更加专注于自身业务,完全不知道其他涉及到的系统功能和服务。这样就降低了负杂性。下面给出一个接近书中作者例子的代码(本来这个例子我不想实现,看看书理解了算了,最后又一想还是动动手吧,眼过千遍不如手过一边。):关于这个例子虽然能运行但也只是个例子,功能没有填充。关于XML文件和AOP也不想多说,这在第二章和第三章都有详细的说明。
 
package  springinaction.chapter01.iocapp;

public  interface  Knight
{
    
public Object embarkOnQuest();
}
// end interface Knight

package  springinaction.chapter01.iocapp;

public  interface  Quest
{
    
public abstract Object embark();//书中的QuestException就不定义了
}
// end interface Quest

package  springinaction.chapter01.iocapp;

public  class  HolyGrailQuest  implements  Quest
{
    
public HolyGrailQuest()
    
{
        
//do something....
    }

    
    
public Object embark()
    
{
        
return new HolyGrailQuest();
    }
//end embark()
    
}
// end class HolyGrailQuest

package  springinaction.chapter01.iocapp;

public  class  KnightOfTheRoundTable  implements  Knight
{
    
private String name;
    
private Quest quest;
    
    
public KnightOfTheRoundTable(String name)
    
{
//        quest = new HolyGrailQuest();
        this.name = name;
        System.out.println(
this.name);
    }

    
    
public HolyGrailQuest embarkOnQuest()
    
{
        
return (HolyGrailQuest)quest.embark();
    }
//end embarkOnQuest()
    
    
public void setQuest(Quest quest)
    
{
        
this.quest = quest;
    }

    
}
// end class KnightOfTheRoundTable

package  springinaction.chapter01.iocapp;

import  java.lang.reflect.Method;
import  org.springframework.aop.MethodBeforeAdvice;
import  org.apache.log4j.Logger;

public  class  MinstrelAdvice  implements  MethodBeforeAdvice
{
    
public MinstrelAdvice()
    
{
        
//do something....
    }

    
    
public void before(Method method, Object[] args, Object target)
    
{
        Knight knight 
= (Knight)target;
        Logger song 
= Logger.getLogger(target.getClass());
        song.debug(
"Brave" + " did " + method.getName());
    }


}

 
 
<? xml version="1.0" encoding="UTF-8" ?>
<! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
< beans >
    
< bean  id  = "quest"
          class 
= "springinaction.chapter01.iocapp.HolyGrailQuest" >
    
</ bean >
    
    
< bean  id  = "knightTarget"
          class 
= "springinaction.chapter01.iocapp.KnightOfTheRoundTable" >
        
< constructor-arg >
            
< value > Bedivere </ value >
        
</ constructor-arg >
        
< property  name  = "quest" >
            
< ref  bean  = "quest" />
        
</ property >
    
</ bean >
    
    
< bean  id  = "minstrel"
          class  
= "springinaction.chapter01.iocapp.MinstrelAdvice" >
    
</ bean >
    
    
< bean  id  = "knight"
          class 
= "org.springframework.aop.framework.ProxyFactoryBean" >
          
< property  name ="proxyInterfaces" >
              
< list >
                  
< value > com.springinaction.chapter01.iocapp.Knight </ value >
              
</ list >
          
</ property >
          
< property  name ="interceptorName" >
              
< list >
                  
< value > minstrel </ value >
              
</ list >
          
</ property >
          
          
< property  name ="target" >
              
< ref  bean  ="knightTarget" />
          
</ property >
    
</ bean >
</ beans >
 
package  springinaction.chapter01.iocapp;

import  org.springframework.beans.factory.BeanFactory;
import  org.springframework.beans.factory.xml.XmlBeanFactory;
import  org.springframework.core.io.FileSystemResource;

public  class  KnightApp
{
    
public static void main(String[] args)
    
{
        BeanFactory factory 
= new XmlBeanFactory(new FileSystemResource("knight.xml"));
        KnightOfTheRoundTable knight 
= (KnightOfTheRoundTable)factory.getBean("knightTarget");
        knight.embarkOnQuest();
    }

}
// end class KnightApp

六、 Spring 比较
在本节中作者重点对Spring和EJB进行了比较,列出了二者的优缺点,并简单给出了何时使用Spring何时使用EJB的建议。还简单介绍了若干其他容器和框架:
l         PicoContaniner:一个最小的轻量级容器,他提供了构造注入和设置注入两种IoC方式。
l         HiveMind:是一个相对而言比较新的IoC容器。(http://jakarta.apache.org/hivemind/)
l         Avalon:最早开发的IoC容器。(http://avalon.apache.org/closed.html)
Web框架有Struts,WebWork,Tapestry,持久层框架有:Hibernate、JDO、OJB、和iBATIS等等。
 
七、小结
通过该章前面简单的了解和实践,我们已经对Spring提供什么功能有了一个好的初步的认识。Spring的目的是简化J2EE开发;Spring的核心概念是IoC和AOP;Spring提供了几种对持久层技术的支持;Spring的事物管理支持是对持久层集成的补充;Spring提供了与各种其他J2EE服务的集成;Spring支持多种视图技术。从第二章开始,将逐个学习Spring的核心技术。

 

 
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1174897
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值