Spring快速入门教程开发你的第一个Spring程序翻译整理:HantsyBai本章学习用strutsMVC框架作前端,Spring做中间层,Hibernate作后端来开发一个简单的Spring应用程序.
在第4章将使用SpringMVC框架对它进行重构.
本章包含以下内容:编写功能性测试.
配置Hibernate和Transaction.
载入Spring的applicationContext.
xml文件.
设置业务代理(businessdelegates)和DAO的依赖性.
把spring写入Struts程序.
概述你将会创建一个简单的程序完成最基本的CRUD(Create,Retrieve,Update和Delete)操作.
这个程序叫MyUsers,作为本书的样例.
这是一个3层架构的web程序,通过一个Action来调用业务代理,再通过它来回调DAO类.
下面的流程图表示了MyUsers是如何工作的.
数字表明了流程的先后顺序,从web层(UserAction)到中间层(UserManager),再到数据层(UserDAO),然后返回.
鉴于大多数读者都比较熟悉struts,本程序采用它作为MVC框架.
Spring的魅力在于它宣称式的事务处理,依懒性的绑定和持久性的支持.
第4章中将用Spring框架对它进行重构.
接下来你会进行以下几个步骤:1.
下载Struts和Spring.
2.
创建项目目录和antBuild文件.
3.
为持久层创建一个单元测试(unittests).
4.
配置Hibernate和Spring.
5.
编写HIbernateDAO的实现.
6.
进行单元测试,通过DAO验证CRUD.
7.
创建一个Manager来声明事务处理.
8.
为strutsAction编写测试程序.
9.
为web层创建一个Action和model(DynaActionForm).
10.
进行单元测试,通过Action验证CRUD.
11.
创建JSP页面,以通过浏览器来进行CRUD操作.
12.
通过浏览器来验证JSP页面的功能.
13.
用velocity模板替换JSP页面.
14.
使用CommonsValidator添加验证.
下载Struts和Spring1.
下载安装以下组件:JDK1.
4.
2(或以上)Tomcat5.
0+Ant1.
6.
1+2.
设置以下环境变量:JAVA_HOMEANT_HOMECATALINA_HOME3.
把以下路径添加到PATH中:JAVA_HOME/binANT_HOME/binCATALINA_HOME/bin为了开发基于java的web项目,开发人员必须事先下载必需的jars,建好开发目录结构和antbuild文件.
对于单一的struts项目,可以利用struts中现成的struts-blank.
war.
对于基于SpringMVC框架的项目,可以用Spring中的webapp-minimal.
war.
这只为开发作准备,两者都没有进行struts-spring集成,也没有考虑单元测试.
为此,我们为读者准备了Equinox.
Equinox为开发Struts-spring式的程序提供一个基本框架.
它已经定义好了目录结构,和antbuild文件(针对compiling,deploying,testing),并且提供了struts,spring,Hibernate开发要用到的jars文件.
Equinox中大部分目录结构和antbuild文件来自我的开源项目AppFuse.
可以说,Equinox是一个简化的AppFuse,它在最小配置情况下,为快速web开发提供了便利.
由于Equinox源于AppFuse,所以在包名,数据库名,及其它地方都找到它的影子.
这是为让你从基于Equinox的程序过渡到更为复杂的AppFuse.
从http://sourcebeat.
com/downloads上下载Equinox,解压到一个合适的位置,开始准备MyUsers的开发.
创建项目目录和antbuild文件为了设置初始的目录结构,把下载的Equinox解压到硬盘.
建议windows用户把项目放在C:Source,Unix/Linux用户放在~/dev(译注:在当前用户目录建一个dev目录)中.
windows用户可以设置一个HOME环境变量,值为C:Source.
最简单的方法是把Equinox解压到你的喜欢的地方,进入equinox目录,运行antnew-Dapp.
anme=myusers.
tips:在windows使用cygwin(www.
cygwin.
org)就可以像Unix/Linux系统一样使用正斜杠,本书所有路径均采用正斜杠.
其它使用反斜杠系统(如windows中命令行窗口)的用户请作相应的调整.
现在MyUsers程序已经有如下的目录结构:Equinox包含一个简单而功能强大的build.
xml,它可以用ant来进行编译,布署,和测试.
ant中已经定义好targets,在equinox运行ant,将看到如下内容:[echo]Availabletargetsare:[echo]compile-->CompileallJavafiles[echo]war-->PackageasWARfile[echo]deploy-->Deployapplicationasdirectory[echo]deploywar-->DeployapplicationasaWARfile[echo]install-->InstallapplicationinTomcat[echo]remove-->RemoveapplicationfromTomcat[echo]reload-->ReloadapplicationinTomcat[echo]start-->StartTomcatapplication[echo]stop-->StopTomcatapplication[echo]list-->ListTomcatapplications[echo]clean-->DeletescompiledclassesandWAR[echo]new-->CreatesanewprojectEquinox支持tomcat的anttasks(任务).
这些已经集成在Equinox中,解讲一下如何进行集成的有助于理解它们的工作原理.
Tomcat和anttomcat中定义了一组任务,可以通过Manager来安装(install),删除(remove),重载(reload)webapps.
要使用这些任务,可以把所有的定义写在一个属性文件中.
在Eqinox的根目录下,有一个名为tomcatTasks.
properties包含如下内容.
deploy=org.
apache.
catalina.
ant.
DeployTaskundeploy=org.
apache.
catalina.
ant.
UndeployTaskremove=org.
apache.
catalina.
ant.
RemoveTaskreload=org.
apache.
catalina.
ant.
ReloadTaskstart=org.
apache.
catalina.
ant.
StartTaskstop=org.
apache.
catalina.
ant.
StopTasklist=org.
apache.
catalina.
ant.
ListTask在build.
xml定义一些任务来安装,删除,重新载入应用程序.
在上面列出的target中,必须定义一些${tomcat.
*}变量.
在根目录下有一个build.
properties默认定义如下:#PropertiesforTomcatServertomcat.
manager.
url=http://localhost:8080/managertomcat.
manager.
username=admintomcat.
manager.
password=admin确保admin用户可以访问Manager应用,打开$CATALINA_HOME/conf/tomcat-users.
xml中是否存在下面一行.
如果不存在,请自己添加.
注意,roles属性可能是一个以逗号(",")隔开的系列.
为了测试所有修改,保存所有文件,启动tomcat.
从命令行中进行myusers目录,运行antlist,可以看到tomcatserver上运行的应用程序.
好了,现在运行antdeploy来安装MyUsers.
打开浏览器,在地址栏中输入http://localhost:8080/myusers,出现如图2.
4的"EquinoxWelcome"画面.
下一节,将写一个User对象和一个维护其持久性的HibernateDAO对象.
用Sping来管理DAO类及其依赖性.
最会写一个业务代理,用到AOP和声明式事务处理.
为持久层编写单元测试在myUsers程序,使用Hibernat作为持久层.
Hinbernate是一个O/R映像框架,用来关联java对象和数据库中的表(tables).
它使得对象的CRUD操作变得非常简单,Spring结合了Hibernate变得更加容易.
从Hibernate转向Spring+Hibernate会减少75%的代码.
这主要是因为,ServiceLocater和一些DAOFactory类的废弃,spring的实时异常代替了Hibernate的检测式的异常.
写一个单元测试有助于规范UserDAO接口.
为UserDAO写一个JUint测试程序,要完成以下几步:1.
在test/org/appfuse/dao下新建一个UserDAOTest.
java类.
它继承了同一个包中的BaseDAOTestCase,其父类初始化了Spring的ApplictionContext(来自web/WEB-INF/applictionContext.
xml),以下是JUnit测试的代码.
packageorg.
appfuse.
dao;//useyourIDEtohandleimportspublicclassUserDAOTestextendsBaseDAOTestCase{privateUseruser=null;privateUserDAOdao=null;protectedvoidsetUp()throwsException{log=LogFactory.
getLog(UserDAOTest.
class);dao=(UserDAO)ctx.
getBean("userDAO");}protectedvoidtearDown()throwsException{dao=null;}publicstaticvoidmain(String[]args){junit.
textui.
TestRunner.
run(UserDAOTest.
class);}}这个类还不能编译,因为还没有UserDAO接口.
在这之前,来写一些来验证User的CRUD操作.
2.
为UserDAOTest类添加testSave和testAddAndRemove方法,如下:publicvoidtestSaveUser()throwsException{user=newUser();user.
setFirstName("Rod");user.
setLastName("Johnson");dao.
saveUser(user);assertTrue("primarykeyassigned",user.
getId()!
=null);log.
info(user);assertTrue(user.
getFirstName()!
=null);}publicvoidtestAddAndRemoveUser()throwsException{user=newUser();user.
setFirstName("Bill");user.
setLastName("Joy");dao.
saveUser(user);assertTrue(user.
getId()!
=null);assertTrue(user.
getFirstName().
equals("Bill"));if(log.
isDebugEnabled()){log.
debug("removinguser.
.
.
");}dao.
removeUser(user.
getId());assertNull(dao.
getUser(user.
getId()));}从这些方法中可以看到,你需要在UserDAO创建以下方法:saveUser(User)removeUser(Long)getUser(Long)getUsers()(返回数据库的所有用户)3.
在src/org/appfuse/dao目录下建一个名为UserDAO.
java类的,输入以下代码:tips:如果你使用eclipse,idea之类的IDE,左边会出现在一个灯泡,提示类不存在,可以即时创建.
packageorg.
appfuse.
dao;//useyourIDEtohandleimportspublicinterfaceUserDAOextendsDAO{publicListgetUsers();publicUsergetUser(LonguserId);publicvoidsaveUser(Useruser);publicvoidremoveUser(LonguserId);}为了UserDAO.
java,UserDAOTest.
java编译通过,还要建一个User.
java类.
4.
在src/org/appfuse/model下建一个User.
java文件,添加几个成员变量:id,firstName,lastName,如下.
packageorg.
appfuse.
model;publicclassUserextendsBaseObject{privateLongid;privateStringfirstName;privateStringlastName;/*用你熟悉的IDE来生成getters和setters,Eclipse中右击>Source->GenerateGettersandSetters*/}注意,你继承了BaseObject类,它包含几个有用的方法:toString(),equlas(),hasCode(),后两个是Hibernate必须的.
建好User后,用IDE打开UserDAO和UserDAOTest两个类,优化导入.
配置Hibernate和Spring现在已经有了POJO(PlainOldJavaObject),写一个映像文件Hibernate就可能维护它.
1.
在org/appfuse/model中新建一个名为User.
hbm.
xml文件,内容如下:2.
在web/WEB-INF/下的applictionContext.
xml中添加映像.
打开文件,找到,改成如下:org/appfuse/model/User.
hbm.
xml在applictionContext.
xml中,你可以看到数据库是怎幺工作的,Hibernate和Spring是如何协作的.
Eqinox会使用名为db/appfuse的HSQL数据库.
它将在你的ant"db"目录下创建,详细配置在"HowSpringIsConfiguredinEquinox"一节中描述.
3.
运行antdeployreload(Tomcat正在运行),在Tomcat控制台的日志中可以看到,数据表正在创建.
INFO-SchemaExport.
execute(98)|Runninghbm2ddlschemaexportINFO-SchemaExport.
execute(117)|exportinggeneratedschematodatabaseINFO-ConnectionProviderFactory.
newConnectionProvider(53)|Initializingconnectionprovider:org.
springframework.
orm.
hibernate.
LocalDataSourceConnectionProviderINFO-DriverManagerDataSource.
getConnectionFromDriverManager(140)|CreatingnewJDBCconnectionto[jdbc:hsqldb:db/appfuse]INFO-SchemaExport.
execute(160)|schemaexportcompleteTip:如果你想看到更多或更少的日志,修改web/WEB-INF/classes/log4j.
xml的设置.
4.
为了验证数据库已经建好,运行antbrowser启动hsqlconsole.
你会看到如的HSQLDatabaseManager.
Equinox中spring是怎幺配置的使用Spring配置任何基于j2ee的web程序都很简单.
至少,你简单的添加Spring的ContextLoaderListener到你的web.
xml中.
org.
springframework.
web.
context.
ContextLoaderListener这是一个ServletContextListener,它会在启动web应用进行初始化.
默认情况下,它会查找web/WEB-INF/applictionContext.
xml文件,你可以指定名为contextConfigLocation的元素来进行修改,例如:contextConfigLocation/WEB-INF/sampleContext.
xml元素可以是以空格或是逗号隔开的一系列路径.
在Equnox中,Spring的配置使用了这个Listener和默认的contextConfigLocation.
那幺,Spring怎幺知道Hibernate的存在这就Spring的魅力所在,它让依赖性的绑定变得非常简单.
请参阅applicationContext.
xml的全部内容:org.
hsqldb.
jdbcDriverjdbc:hsqldb:db/appfusesaorg/appfuse/model/User.
hbm.
xmlnet.
sf.
hibernate.
dialect.
HSQLDialectcreate第一bean代表HSQL数据库,Spring仅仅是调用LocalSessionFactoryBeanr的setDataSource(DataSource)使之工作.
如果你想用JNDIDataSource替换,可以bean的定义改成类似下面的几行:java:comp/env/jdbc/appfusehibernate.
hbm2ddl.
auto属性在sessionFactory定义中,这个属性是为了在应用启动时自动创建表,也可能是update或create-drop.
最后一个bean是transactionManager(你也可以使用JTAtransaction),在处理跨越两个数据库的分布式的事务处理中尤其重要.
如果你想使用jtatransactionmanager,将此bean的class属性改成org.
springframework.
transaction.
jta.
JtaTransactionManager下面实现UserDAO类.
用hibernate实现UserDAO为了实现HibernateUserDAO,需要完成以下几步:1.
在src/org/appfuse/dao/hibernate(你要新建这个目录/包)新建一个文件UserDAOHibernate.
ava.
这个类继承了HibernatDaoSupport类,并实现了UserDAO接口.
packageorg.
appfuse.
dao.
hibernate;//useyourIDEtohandleimportspublicclassUserDAOHibernateextendsHibernateDaoSupportimplementsUserDAO{privateLoglog=LogFactory.
getLog(UserDAOHibernate.
class);publicListgetUsers(){returngetHibernateTemplate().
find("fromUser");}publicUsergetUser(Longid){return(User)getHibernateTemplate().
get(User.
class,id);}publicvoidsaveUser(Useruser){getHibernateTemplate().
saveOrUpdate(user);if(log.
isDebugEnabled()){log.
debug(userIdsetto:+user.
getID());}}publicvoidremoveUser(Longid){Objectuser=getHibernateTemplate().
load(User.
class,id);getHibernateTemplate().
delete(user);}}Spring的HibernateDaoSupport类是一个方便实现HibernateDAO的超类,你可以它的一些有用的方法,来获得HibernateDAO或是SessionFactory.
最方便的方法是getHibernateTemplate(),它返回一个HibernateTempalte对象.
这个模板把检测式异常(checkedexception)包装成实时式异常(runtimeexception),这使得你的DAO接口无需抛出Hibernate异常.
程序还没有把UserDAO绑定到UserDAOHibernate上,必须创建它们之间的关联.
2.
在Spring配置文件(web/WEB-INF/applictionContext.
xml)中添加以下内容:这样就在你的UserDAOHibernate(从HibernateDaoSupport的setSessionFactory继承)中建了一个HibernateSessionFactory.
Spring会检测一个Session(也就是,它在web层是开放的)是否已经存在,并且直接使用它,而不是新建一个.
这样你可以使用Spring流行的"OpenSessioninView"模式来载入collections.
进行单元测试,来验证DAO的CRUD操作在进行第一个测试之前,把你的日志级别从"INFO"调到"WARN".
1.
把log4j.
xml(在web/WEB-INF/classes目录下)中改为.
2.
键入anttest来运行UserDAOTest.
如果你有多个测试,你必须用anttest-Dtestcase=UserDAOTest来指定要运行的测试.
运行之后,你会如下类似的一些日志信息.
创建Manager,声明事务处理(createmanageranddeclaretransactions)J2EE开发中建议将各层进行分离.
换言之,不要把数据层(DAOs)和web层(servlets)混在一起.
使用Spring,很容易做到这一点,但使用"业务代理"(businessdelegate)模式,可以对这些层进一步分离.
使用业务代理模式的主要原因是:大多数持久层组件执行一个业务逻辑单元,把逻辑放在一非web类中的最大好处是,webservice或是丰富平台客户端(richplatformclient)可以像使用servlet一样来用同一API.
大多数业务逻辑都在同一方法中完成,当然可能多个DAO.
使用业务代理,使得你可以高级业务代理层(level)使用Spring的声明式业务代理特性.
MyUsers应用中UserManager和UserDAO拥有相同的一个方法.
主要不同的是Manager对于web更为友好(web-friendly),它可以接受Strings,而UserDAO只能接受Longs,并且它可以在saveUser方法中返回一个User对象.
这在插入一个新用户比如,要获得主键,是非常方便的.
Manager(或称为业务代理)中也可以添加一些应用中所需要的其它业务逻辑.
HostKvm 商家我们算是比较熟悉的国内商家,商家主要还是提供以亚洲数据中心,以及直连海外线路的服务商。这次商家有新增香港和俄罗斯两个机房的高防服务器方案。默认提供30GB防御,且目前半价优惠至4.25美元起步,其他方案的VPS主机还是正常的八折优惠。我们看看优惠活动。香港和俄罗斯半价优惠:2021fall,限购100台。通用优惠码:2021 ,八折优惠全部VPS。我们看看具体的套餐。1、香港高...
提速啦简单介绍下提速啦 是成立于2012年的IDC老兵 长期以来是很多入门级IDC用户的必选商家 便宜 稳定 廉价 是你创业分销的不二之选,目前市场上很多的商家都是从提速啦拿货然后去分销的。提速啦最新物理机活动 爆炸便宜的香港CN2物理服务器 和 日本CN2物理服务器香港CTG E5 2650 16G内存 20M CN2带宽 1T硬盘 150元/月日本CN2 E5 2650 16G内存 20M C...
青云互联怎么样?青云互联是一家成立于2020年的主机服务商,致力于为用户提供高性价比稳定快速的主机托管服务,目前提供有美国免费主机、香港主机、韩国服务器、香港服务器、美国云服务器,香港安畅cn2弹性云限时首月五折,15元/月起;可选Windows/可自定义配置,让您的网站高速、稳定运行。点击进入:青云互联官方网站地址青云互联优惠码:八折优惠码:ltY8sHMh (续费同价)青云互联香港云服务器活动...