petclinic閱讀筆記
1
、
Web
程序的設(shè)計(jì)原則:
The following items should be noted regarding the web application implementation design:
-
all JSP's are stored under /WEB-INF/jsp except for index.jsp which is the configured "welcome-file"
-
The use of JSP technology in the application is not exposed to the user, i.e., the end user never sees a URL ending in ".jsp".
-
By convention, all URL's in the application ending in ".do" are handled by web application controllers. Static html pages ending in ".html", such as Javadoc, will be directly served to the end user.
-
The results of all form entries are handled using browser round trip redirection to minimize possible end user confusion.
-
All pages are extremely simple JSP implementations that focus only on providing the necessary functionality.
-
References to Entity objects are passed around in the application by supplying the object's
ID
as a request parameter.
下面的幾項(xiàng)應(yīng)該在
Web
程序的設(shè)計(jì)實(shí)現(xiàn)中被關(guān)注:
1.?????
除了處理
index.jsp
這個(gè)被被配置為歡迎頁面的頁面外,所有的
JSP
頁面放置在
/WEB-INF/jsp
下面。
2.?????
這樣的使用
JSP
技術(shù)是不被用戶接受的,所以,最終用戶永遠(yuǎn)也不應(yīng)該看到
URL
以
".jsp
"
結(jié)尾。
3.?????
根據(jù)協(xié)議,在程序的所有
URL
都以
".do"
結(jié)尾以便于被
web
程序
controllers
處理。靜態(tài)
html
頁面以
".html"
結(jié)尾,例如
Javadoc,
將直接對(duì)最終用戶服務(wù)。
4.?????
對(duì)于被瀏覽器處理的所有的表單實(shí)體對(duì)象的結(jié)果的往返傳遞應(yīng)該盡可能地降低用戶理解的混亂。
5.?????
所有的頁面盡可能的簡單,
JSP
的實(shí)現(xiàn)集中在僅僅提供必須的功能。
6.?????
對(duì)于實(shí)體對(duì)象的引用應(yīng)該是將對(duì)象
ID
作為
request
參數(shù)在應(yīng)用程序中的傳遞來提供的。
2
、
JNDI Dababase connections pools
技術(shù)
我使用
PetClinic Tutorial
中介紹的方法根本不能實(shí)現(xiàn)。我想應(yīng)該是
Tutorial
中介紹的不全面或者是我有什么地方不正確,這里先留著,等以后能上網(wǎng)后在搞定,后面使用
Tomcat
推薦的方式來實(shí)現(xiàn)。
在
context.xml
中作如下配置:
<Resource name="jdbc/petclinicMYSQL" auth="Container" type="javax.sql.DataSource" maxActive="50"
maxIdle="10" maxWait="10000" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"
????? driverClassName="org.gjt.mm.mysql.Driver" username="pc" password="pc"
????? url="jdbc:mysql://localhost:3306/petclinic?autoReconnect=true"/>
在
web.xml
中作如下配置:
??????
?????? <resource-ref>
????????????? <res-ref-name>jdbc/petclinicMYSQL</res-ref-name>
????????????? <res-type>javax.sql.DataSource</res-type>
????????????? <res-auth>Container</res-auth>
?????? </resource-ref>
聲明那個(gè)你將要請(qǐng)求的使用的
JNDI
的名稱。
3
、
Spring2.0
的
幾個(gè)
annotation
支持
1
)、
@Service
org.springframework.stereotype.Service??????
指明一個(gè)被注解的類是一個(gè)“
Service
”
(
例如
.
一個(gè)業(yè)務(wù)服務(wù)門面
)
。
這個(gè)
annotation
當(dāng)作一種特性的
@Component
被使用,允許
classpath
掃描自動(dòng)探測(cè)。
2
)、
@ManagedResource
org.springframework.jmx.export.annotation.ManagedResource
JDK 1.5+
類庫級(jí)別的
annotaion
用來指明注冊(cè)一個(gè)使用了
JMX
服務(wù)器和
ManagedResource
屬性通信的類的實(shí)例。
4
、
Spring2.0
的
JDBC
支持
1
)、
org.springframework.jdbc.core.support.JdbcDaoSupport
DAO
的便利的父類。需要一個(gè)
javax.sql.DataSource
,通過
getJdbcTemplate()
方法提供一個(gè)
org.springframework.jdbc.core.JdbcTemplate
給子類。
這個(gè)基礎(chǔ)類主要供
JdbcTemplate
使用,但是它也可以在一個(gè)直接連接或者使用
org.springframework.jdbc.object
包中的類操作對(duì)象。
這個(gè)類也就是給實(shí)現(xiàn)
DAO
的提供了一個(gè)模版。
??????
2
)、
org.springframework.jdbc.object.MappingSqlQuery
一個(gè)有用的查詢工具類其具體的子類必須實(shí)現(xiàn)
abstract
的
mapRow(ResultSet ,int)
方法去將
JDBCResultSet
的每一行轉(zhuǎn)換為一個(gè)對(duì)象。
通過減少參數(shù)和上下文信息簡化了
MappingSqlQueryWithParameters API
。絕大多數(shù)的子類不用關(guān)心參數(shù)。如果你不使用上下文相關(guān)的信息,這個(gè)子類將取代
MappingSqlQueryWithParameters
。
org.springframework.jdbc.object.RdbmsOperation.compile()
編譯這個(gè)
Query
語句,忽略以后的編譯。做的其實(shí)就是設(shè)置
preparedStatementFactory
的參數(shù),為該查詢語句的查詢做好準(zhǔn)備。必須在構(gòu)造方法中編譯,否則無法生成指定的
PreparedStatement
。
3
)、
org.springframework.jdbc.core.SqlParameter
代表一個(gè)
SQL
參數(shù)定義的對(duì)象。
參數(shù)可以是匿名的,如
”name”
屬性可以是
null
。但是,所有的參數(shù)必須一個(gè)根據(jù)
java.sql.Types
定義了
SQL
類型。
4
)、
org.springframework.jdbc.object.SqlUpdate
可重用的操作對(duì)象代表了一個(gè)
SQL undate
。
這個(gè)類提供一個(gè)許多的
update
方法,就類似于
query
對(duì)象中的
execute
方法。
這個(gè)類是具體的。盡管它可以被子類化
(
例如去增加一個(gè)自定義的
update
方法
)
,但是能很容易的通過設(shè)置
SQL
語句和聲明參數(shù)來參數(shù)化。
就像所有裝載在
Spring
框架中的
RdbmsOperation
類一樣,
SqlQuery
實(shí)例在其初始化完成后是線程安全的。準(zhǔn)確的說,在它們通過它們的
setter
方法構(gòu)造和配置后,它們能在多線程中安全使用。
?????? 5
)、
HibernateTemplate
的
merge
方法。
??????
注意:
Hibernate3
的
merge
操作不能在當(dāng)前的
HibernateSession
中再次組合
entity
。作為替代,它將總是拷貝狀態(tài)到一個(gè)注冊(cè)了的這個(gè)
entity
的代表。新的
entity
它將會(huì)注冊(cè)一個(gè)拷貝,但是將不會(huì)更新傳遞進(jìn)來的對(duì)象的
id
。為了仍然更新原始的
object
的
id
,我們需要在我們的
SessionFactory
中注冊(cè)一個(gè)
Spring
的
IdTransferringMergeEventListener
。
典型的使用情況是,將
IdTransferringMergeEventListener
作為一個(gè)
entry
,使用“
merge
”鍵值,配置到
LocalSessionFactoryBean
得
”eventListeners”
的
Map
中。
5
、
Spring2.5
的
Annotation
支持
???????? 1
)、
@Repository
org.springframework.stereotype.Repository
??????
指出一個(gè)注解的類是“
Repository
(倉庫)”(或者“
DAO
”)。
??????
一個(gè)這樣注解的類是能夠使用
Spring org.springframework.dao.DataAccessException
處理異常合格的類了。注解過的類也能夠作為整個(gè)程序體系的工具類使用,例如
aspects
等等。
??????
到
Spring2.5
為止,這個(gè)
annotation
也能夠作為一個(gè)特殊的
@Component
來使用。允許使注解過的類通過
classpath
掃描來自動(dòng)裝配。
2
)、
@Transactional
org.springframework.transaction.annotation.Transactional
??????
在一個(gè)方法或類上描述事務(wù)屬性。
??????
這個(gè)注解類型一般能夠直接與
Spring
的
org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
相比較,而且實(shí)際上
AnnotationTransactionAttributeSource
也能夠直接將數(shù)據(jù)轉(zhuǎn)換成接下的類,因此
Spring
的事務(wù)支持代碼不必要去了解
annotations
。假如沒有
exception
相關(guān)的規(guī)則,它將會(huì)當(dāng)作
org.springframework.transaction.interceptor.DefaultTransactionAttribute
(在運(yùn)行時(shí)異常發(fā)生的時(shí)候回滾)。
3
)、
@Autowired
org.springframework.beans.factory.annotation.Autowired
????????
標(biāo)記一個(gè)構(gòu)造器,域,
setter
方法或者配置方法能夠被
Spring
依賴注入的工具自動(dòng)綁定。
??????
任何給定的類最多只有一個(gè)構(gòu)造器可能帶有該注解,標(biāo)志這個(gè)類作為一個(gè)
Spring bean
使用時(shí),標(biāo)志這個(gè)構(gòu)造器自動(dòng)綁定。這樣的構(gòu)造器不必一定是
public
的。
??????
域在一個(gè)
bean
構(gòu)造器調(diào)用后,所有的配置方法被調(diào)用前,被注入。這樣的配置域不必一定是
public
的。
??????
配置方法可以擁有任意的名字和任意數(shù)量的參數(shù);那些參數(shù)中的每一個(gè)將在
Spring
容器中匹配的
bean
自動(dòng)綁定。
Bean
屬性
setter
方法是一個(gè)特殊的配置方法。這樣的配置方法不必一定是
public
的。
??????
在多參方法的情況下,‘
required
’屬性可應(yīng)用到所有的參數(shù)中。
??????
在一個(gè)依賴
java.util.Collection
或者
java.util.Map
的情況下,這個(gè)容器將自動(dòng)綁定所有的
bean
并匹配聲明的值類型。當(dāng)
Map
的情況下,
key
必須是
String
類型的并且將會(huì)解析成相應(yīng)的
bean
的名字。
??????
請(qǐng)考慮閱讀
AutowiredAnnotationBeanPostProcessor
類
(
默認(rèn),檢查這個(gè)
annotation
是否存在
)
的
javadoc
。
4
)、
@ Controller
org.springframework.stereotype.Controller
??????
指出一個(gè)注解的淚是一個(gè)“
Controller
”
(
一個(gè)
Web
控制器
)
。
??????
這個(gè)
annotation
作為一個(gè)特殊的
@Component
使用,允許實(shí)現(xiàn)類通過
classpath
掃描自動(dòng)發(fā)現(xiàn)。典型的使用是,結(jié)合基于
org.springframework.web.bind.annotation.RequestMapping
注解的注解的處理器方法。
5
)、
@RequestMapping
org.springframework.web.bind.annotation.RequestMapping
??????
映射
web
請(qǐng)求到特殊處理器類及(或)處理方法。在
Servlet
和
Portlet
環(huán)境中提供一致的方式,通過語義結(jié)合具體的環(huán)境。
??????
注意:方法級(jí)別的映射僅僅允許縮小類級(jí)別的映射表達(dá)。
HTTP paths/portlet modes
需要唯一地映射到特殊的處理
bean
,所有給定的
path/mode
僅允許被映射成一個(gè)特殊的處理器
bean
(不會(huì)延伸過多處理器
bean
)。強(qiáng)烈的推薦將彼此相關(guān)的處理方法放到相同
bean
中。使用該注解注解過的處理方法被允許擁有靈活的簽名。它們可以擁有任意排列的如下類型的參數(shù)
(
除了驗(yàn)證結(jié)果外,如果需要,它們需要驗(yàn)證相關(guān)的
command
對(duì)象正確
)
:
?
·???????
請(qǐng)求及
/
或響應(yīng)對(duì)象(
Servlet API
或者
Portlet API
)。你可以選擇任何特殊的
request/response
類型,例如
javax.servletRequest/javax.servlet.http.HttpServletRequest
或者
javax.portlet.PortletRequest / javax.portlet.ActionRequest / javax.portlet.RenderRequest
。注意
Portlet
情況下,一個(gè)明確的聲明為
action / render
參數(shù)也能用作映射特殊的
request
類型成一個(gè)處理器方法。(以防,沒有其它給定的
action
和
render
請(qǐng)求的區(qū)別的信息)。
·???????
? Session
對(duì)象(
Servlet API
或者
Portlet API
):
javax.servlet.http.HttpSession
或者
javax.portlet.PortletSession
。一個(gè)這樣類型的參數(shù)將強(qiáng)迫相應(yīng)類型的
session
的存在。結(jié)果,這樣一個(gè)參數(shù)將不能使
null
。注意
session
的訪問可能不是線程安全的,特別是一個(gè)
servlet
環(huán)境:考慮改換
”synchronizeOnSession”
標(biāo)記為
”true”
假如多重請(qǐng)求容許同時(shí)訪問一個(gè)
session
。
·???????
略。
6
)、
@SessionAttributes
org.springframework.web.bind.annotation.SessionAttributes
??????
指出一個(gè)特殊的處理器使用的
session
屬性的注解。這個(gè)將列出將被透明的存儲(chǔ)在
session
或者一些對(duì)話存儲(chǔ)中的
model
屬性的名字,作為
form-backing bean
使用。在類級(jí)別使用中,應(yīng)用為注解過的處理類操作的
model
屬性。
??????
注意:使用這個(gè)
annotation
的
Session
屬性是滿足一個(gè)特殊處理器
model
屬性需要的。
透明的存儲(chǔ)在一個(gè)對(duì)話
session
中。那些屬性將會(huì)在完成處理器的需要后從
session
中刪除。因此,在一個(gè)特殊的處理器對(duì)話期間內(nèi),使用這個(gè)工具操作被期望臨時(shí)存儲(chǔ)在
session
中的會(huì)話屬性。
??????
要用到永久的
session
屬性,例如,一個(gè)用戶鑒定對(duì)象,請(qǐng)使用傳統(tǒng)的
session.setAttribute
方法代替。可選擇地,考慮使用
org.springframework.web.context.request.WebRequest
接口的屬性管理功能。
6
、
Spring2.5
新加的
schema tag
。
?????? 1
)、
Context tags
用來處理涉及到
plumbing
的
ApplicationContext
配置。也就是說,不是通常的對(duì)于終端用戶重要的
bean
,而是是處理許多
Spring
中日常事務(wù)的更重要的
Bean
,例如
BeanfactoryPostProcessor
。下面是使
context
命名空間對(duì)你起作用的正確的
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"
??????????????
?? xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- <bean/> definitions here -->
?????????????
??????
????????????????????????????????????????????????
注意:該
tag
在
Spring2.5
中才起作用。
<context:property-placeholder location="classpath:jdbc.properties"/>
??
這個(gè)元素通過指定的屬性文件的地址,使替代標(biāo)識(shí)
${…}placeholders
得以活動(dòng)。這個(gè)元素是一個(gè)方便的機(jī)制,它通過建立一個(gè)
PropertyPlaceholderConfigurer
給你提供一個(gè)方便的機(jī)制;如果你需要更多的控制
PropertyPlaceholderConfigurer
,那么你自己建一個(gè)吧。
<context:annotation-config/>
使
Spring
基礎(chǔ)組織中的能夠自動(dòng)偵查
bean
類的各種
annotations
:
Spring
的
@Required
和
@Autowired
,還有
JSR 250
規(guī)范中的
@PostConstruct
,
@PreDestroy
和
@Resource
(如果可用的話)還有
JPA
的
@PersistenceContext
和
@PersistenceUnit
(如果可用的話)。作為選擇,你可以選擇使用單獨(dú)的
BeanPostProcessors
來處理那些
annotations
。
注意:這個(gè)元素不能激活對(duì)
Spring
的
@Transactional annotation
的處理。請(qǐng)使用
<tx:annotation-driven/>
元素來達(dá)到目的。
<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
??????
這個(gè)元素能夠掃描并自動(dòng)偵測(cè)到指定的包中的標(biāo)識(shí)為
@Components
的類。
?????????? -
總結(jié)
:
petclinic
是
Spring
組織給出的
Spring
使用的示例程序。
??????
?
該程序未將領(lǐng)域?qū)ο蠛推渌臉I(yè)務(wù)類沒嚴(yán)格分開(沒有明確的分包來標(biāo)識(shí)),而且
Business
層和持久層更是根本混合一起,不是很好的實(shí)踐,因?yàn)槌志脤拥念悾谷皇菑?/font>
Business
層的類繼承而來,比如
SimpleJdbcClinic
和
HibernateClinic
都是繼承至
Clinic
這個(gè)核心業(yè)務(wù)的
DAO
類
(
很顯然混合就是從這里開始了
)
。
在手冊(cè)中提到,該程序主要是用來展示各種的
Spring
數(shù)據(jù)訪問策略,而僅帶有極其簡單的業(yè)務(wù)邏輯,所有為了開發(fā)效率將業(yè)務(wù)層和持久層混合一起。很顯然,這里如果我們改變業(yè)務(wù)方法的話,就需要幾乎修改所有的持久化類了。
我想更好的方式是將持久類對(duì)象
Bean
注入到業(yè)務(wù)類中。因?yàn)榻M合永遠(yuǎn)優(yōu)于繼承,并且如果使用
Spring
進(jìn)行依賴注入的話會(huì)更優(yōu)良。
使用
Spring
的
MVC
框架,這是一個(gè)很優(yōu)良的框架,比
Struts1.X
要強(qiáng)很多。
使用了
Spring
的
JMX
支持
API
,
JMX
是一個(gè)基于
RMI
和
JNDI
的
Java
管理擴(kuò)展
API
。
使用了
Spring
的聲明式事務(wù)管理
API
。
使用
apache
的
DBCP
數(shù)據(jù)庫連接池技術(shù)。
在
petclinic2.5
版中,使用了
annotation
方式進(jìn)行各種
Spring
配置。
Annotation
方式雖然提高了學(xué)習(xí)成本,但是無疑是比描述文檔更優(yōu)的策略,因?yàn)樗鼫p少了程序員的編寫描述文件成本,而且能提供編譯器的檢查,程序員不用再去編寫可能使我們頭腦炸掉的
XML
描述文檔。
Spring
的
AOP
支持,雖然這個(gè)程序中使用了幾個(gè)很無聊的切面。
posted on 2009-11-04 21:15 vagasnail 閱讀(790) 評(píng)論(0) 編輯 收藏 所屬分類: Java Web