petclinic阅读笔记
				
						1
				
				
						、
				
				
						Web 
				
				
						程序的设计原则:
				
				
						
																
				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. 
 
				下面的几项应该在
				Web
				程序的设计实现中被关注:
				
						
				
						1.      
				
				除了处理
				index.jsp
				这个被被配置为欢迎页面的页面外,所有的
				JSP
				页面放置在
				/WEB-INF/jsp 
				下面。
				
						
				
						2.      
				
				这样的使用
				JSP
				技术是不被用户接受的,所以,最终用户永远也不应该看到
				URL
				以
				
						
								".jsp
						
				
				"
				结尾。
				
						
				
						3.      
				
				根据协议,在程序的所有
				URL
				都以
				
						
								".do"
						
				
				结尾以便于被
				web
				程序
				controllers
				处理。静态
				html
				页面以
				
						
								".html"
						
				
				结尾,例如
				Javadoc,
				将直接对最终用户服务。
				
						
				
						4.      
				
				对于被浏览器处理的所有的表单实体对象的结果的往返传递应该尽可能地降低用户理解的混乱。
				
						
				
						5.      
				
				所有的页面尽可能的简单,
				JSP
				的实现集中在仅仅提供必须的功能。
				
						
				
						6.      
				
				对于实体对象的引用应该是将对象
				ID
				作为
				request
				参数在应用程序中的传递来提供的。
				
						
				
						
				
						2
				
				
						、
				
				
						JNDI Dababase connections pools 
				
				
						技术
				
				
						
								
				我使用
				PetClinic Tutorial
				中介绍的方法根本不能实现。我想应该是
				Tutorial
				中介绍的不全面或者是我有什么地方不正确,这里先留着,等以后能上网后在搞定,后面使用
				Tomcat
				推荐的方式来实现。
				
						
				在
				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>
				声明那个你将要请求的使用的
				JNDI 
				的名称。
				
						
				
						
				
						3
				
				
						、
				
				
						Spring2.0 
				
				
						的
				
				
						
						
				
				
						几个
				
				
						
								annotation 
						
				
				
						支持
				
				
						
								
				1
				)、
				@Service
				org.springframework.stereotype.Service       
				指明一个被注解的类是一个“
				Service
				”
				(
				例如
				.
				一个业务服务门面
				)
				。
				
						
				这个
				annotation 
				当作一种特性的
				@Component
				被使用,允许
				classpath
				扫描自动探测。
				
						
								
				2
				)、
				@ManagedResource
				org.springframework.jmx.export.annotation.ManagedResource
				JDK 1.5+ 
				类库级别的
				annotaion
				用来指明注册一个使用了
				JMX
				服务器和
				ManagedResource
				属性通信的类的实例。
				
						
				
						
				
						4
				
				
						、
				
				
						Spring2.0
				
				
						的
				
				
						JDBC
				
				
						支持
				
				
						
								
				
						1
				
				
						)、
				
				
						org.springframework.jdbc.core.support.JdbcDaoSupport
				DAO
				的便利的父类。需要一个
				javax.sql.DataSource
				,通过
				getJdbcTemplate()
				方法提供一个
				org.springframework.jdbc.core.JdbcTemplate
				给子类。
				
						
				这个基础类主要供
				JdbcTemplate
				使用,但是它也可以在一个直接连接或者使用
				org.springframework.jdbc.object
				包中的类操作对象。
				
						
				这个类也就是给实现
				DAO
				的提供了一个模版。
				
						
				
						
				
						
								       
						
						2
				
				)、
				
						org.springframework.jdbc.object.MappingSqlQuery 
				
		
				一个有用的查询工具类其具体的子类必须实现
				abstract
				的
				mapRow(ResultSet ,int)
				方法去将
				JDBCResultSet
				的每一行转换为一个对象。
				
						
				通过减少参数和上下文信息简化了
				MappingSqlQueryWithParameters API
				。绝大多数的子类不用关心参数。如果你不使用上下文相关的信息,这个子类将取代
				MappingSqlQueryWithParameters
				。
				
						
				org.springframework.jdbc.object.RdbmsOperation.compile() 
				编译这个
				Query
				语句,忽略以后的编译。做的其实就是设置
				preparedStatementFactory
				的参数,为该查询语句的查询做好准备。必须在构造方法中编译,否则无法生成指定的
				PreparedStatement
				。
				
						
				
						
				
						3
				
				
						)、
				
				
						org.springframework.jdbc.core.SqlParameter
				代表一个
				SQL
				参数定义的对象。
				
						
				参数可以是匿名的,如
				”name”
				属性可以是
				null
				。但是,所有的参数必须一个根据
				java.sql.Types
				定义了
				SQL
				类型。
				
						
				
						
				
						4
				
				
						)、
				
				
						org.springframework.jdbc.object.SqlUpdate
				可重用的操作对象代表了一个
				SQL undate
				。
				
						
				这个类提供一个许多的
				update
				方法,就类似于
				query
				对象中的
				execute
				方法。
				
						
				这个类是具体的。尽管它可以被子类化
				(
				例如去增加一个自定义的
				update
				方法
				)
				,但是能很容易的通过设置
				SQL
				语句和声明参数来参数化。
				
						
				就像所有装载在
				Spring
				框架中的
				RdbmsOperation
				类一样,
				SqlQuery
				实例在其初始化完成后是线程安全的。准确的说,在它们通过它们的
				setter
				方法构造和配置后,它们能在多线程中安全使用。
				
						
				
						
								       5
				
				
						)、
				
				
						HibernateTemplate
				
				
						的
				
				
						merge
				
				
						方法。
				
				
						
								
				
						       
				
				注意:
				Hibernate3
				的
				merge
				操作不能在当前的
				HibernateSession
				中再次组合
				entity
				。作为替代,它将总是拷贝状态到一个注册了的这个
				entity
				的代表。新的
				entity
				它将会注册一个拷贝,但是将不会更新传递进来的对象的
				id
				。为了仍然更新原始的
				object
				的
				id
				,我们需要在我们的
				SessionFactory
				中注册一个
				Spring
				的
				IdTransferringMergeEventListener
				。
				
						
				典型的使用情况是,将
				IdTransferringMergeEventListener
				作为一个
				entry
				,使用“
				merge
				”键值,配置到
				LocalSessionFactoryBean
				得
				”eventListeners”
				的
				Map
				中。
				
						
				
						5
				
				
						、
				
				
						Spring2.5
				
				
						的
				
				
						Annotation
				
				
						支持
				
				
						
								
				
						
								         1
				
				)、
				
						@Repository
						
								
								 
						
				
		
				
						org.springframework.stereotype.Repository 
				
		
				
						       
				
				指出一个注解的类是“
				Repository
				(仓库)”(或者“
				DAO
				”)。
				
						
				
						       
				
				一个这样注解的类是能够使用
				Spring org.springframework.dao.DataAccessException
				处理异常合格的类了。注解过的类也能够作为整个程序体系的工具类使用,例如
				aspects
				等等。
				
						
				
						       
				
				到
				Spring2.5
				为止,这个
				annotation
				也能够作为一个特殊的
				@Component
				来使用。允许使注解过的类通过
				classpath
				扫描来自动装配。
				
						
				
						2
				
				)、
				
						@Transactional 
				
		
				
						org.springframework.transaction.annotation.Transactional 
				
		
				
						       
				
				在一个方法或类上描述事务属性。
				
						
				
						       
				
				这个注解类型一般能够直接与
				Spring
				的
				org.springframework.transaction.interceptor.RuleBasedTransactionAttribute
				相比较,而且实际上
				AnnotationTransactionAttributeSource
				也能够直接将数据转换成接下的类,因此
				Spring
				的事务支持代码不必要去了解
				annotations
				。假如没有
				exception
				相关的规则,它将会当作
				org.springframework.transaction.interceptor.DefaultTransactionAttribute
				(在运行时异常发生的时候回滚)。
				
						
				3
				)、
				@Autowired
				
						org.springframework.beans.factory.annotation.Autowired 
				
		
				
						
								         
						
				
				标记一个构造器,域,
				setter
				方法或者配置方法能够被
				Spring
				依赖注入的工具自动绑定。
				
						
				
						       
				
				任何给定的类最多只有一个构造器可能带有该注解,标志这个类作为一个
				Spring bean
				使用时,标志这个构造器自动绑定。这样的构造器不必一定是
				public
				的。
				
						
				
						       
				
				域在一个
				bean
				构造器调用后,所有的配置方法被调用前,被注入。这样的配置域不必一定是
				public
				的。
				
						
				
						       
				
				配置方法可以拥有任意的名字和任意数量的参数;那些参数中的每一个将在
				Spring
				容器中匹配的
				bean
				自动绑定。
				Bean
				属性
				setter
				方法是一个特殊的配置方法。这样的配置方法不必一定是
				public
				的。
				
						
				
						       
				
				在多参方法的情况下,‘
				required
				’属性可应用到所有的参数中。
				
						
				
						       
				
				在一个依赖
				java.util.Collection
				或者
				java.util.Map
				的情况下,这个容器将自动绑定所有的
				bean
				并匹配声明的值类型。当
				Map
				的情况下,
				key
				必须是
				String
				类型的并且将会解析成相应的
				bean
				的名字。
				
						
				
						       
				
				请考虑阅读
				AutowiredAnnotationBeanPostProcessor
				类
				(
				默认,检查这个
				annotation
				是否存在
				)
				的
				javadoc
				。
				
						
				4
				)、
				@ Controller
				
						org.springframework.stereotype.Controller 
				
		
				
						       
				
				指出一个注解的泪是一个“
				Controller
				”
				(
				一个
				Web 
				控制器
				)
				。
				
						
				
						       
				
				这个
				annotation
				作为一个特殊的
				@Component
				使用,允许实现类通过
				classpath
				扫描自动发现。典型的使用是,结合基于
				org.springframework.web.bind.annotation.RequestMapping 
				注解的注解的处理器方法。
				
						
				5
				)、
				@RequestMapping
				
						org.springframework.web.bind.annotation.RequestMapping 
				
		
				
						       
				
				映射
				web
				请求到特殊处理器类及(或)处理方法。在
				Servlet
				和
				Portlet
				环境中提供一致的方式,通过语义结合具体的环境。
				
						
				
						       
				
				注意:方法级别的映射仅仅允许缩小类级别的映射表达。
				HTTP paths/portlet modes 
				需要唯一地映射到特殊的处理
				bean
				,所有给定的
				path/mode
				仅允许被映射成一个特殊的处理器
				bean
				(不会延伸过多处理器
				bean
				)。强烈的推荐将彼此相关的处理方法放到相同
				bean
				中。使用该注解注解过的处理方法被允许拥有灵活的签名。它们可以拥有任意排列的如下类型的参数
				(
				除了验证结果外,如果需要,它们需要验证相关的
				command
				对象正确
				)
				:
				
						  
						
				
						·        
				
				
						
						
						
						
				
				请求及
				/
				或响应对象(
				Servlet API 
				或者
				Portlet API
				)。你可以选择任何特殊的
				request/response
				类型,例如
				javax.servletRequest/javax.servlet.http.HttpServletRequest 
				或者
				javax.portlet.PortletRequest / javax.portlet.ActionRequest / javax.portlet.RenderRequest
				。注意
				Portlet
				情况下,一个明确的声明为
				action / render 
				参数也能用作映射特殊的
				request
				类型成一个处理器方法。(以防,没有其它给定的
				action
				和
				render
				请求的区别的信息)。
				
						
				
						·        
				
				
						  Session
				对象(
				Servlet API 
				或者
				Portlet API
				):
				javax.servlet.http.HttpSession
				或者
				javax.portlet.PortletSession
				。一个这样类型的参数将强迫相应类型的
				session
				的存在。结果,这样一个参数将不能使
				null
				。注意
				session
				的访问可能不是线程安全的,特别是一个
				servlet
				环境:考虑改换
				”synchronizeOnSession”
				标记为
				”true”
				假如多重请求容许同时访问一个
				session
				。
				
						
				
						·        
				
				略。
				
						
				
						
								
				6
				)、
				@SessionAttributes
				
						org.springframework.web.bind.annotation.SessionAttributes
				
						       
				
				指出一个特殊的处理器使用的
				session
				属性的注解。这个将列出将被透明的存储在
				session
				或者一些对话存储中的
				model
				属性的名字,作为
				form-backing bean
				使用。在类级别使用中,应用为注解过的处理类操作的
				model
				属性。
				
						
				
						       
				
				注意:使用这个
				annotation
				的
				Session
				属性是满足一个特殊处理器
				model
				属性需要的。
				
						
				透明的存储在一个对话
				session
				中。那些属性将会在完成处理器的需要后从
				session
				中删除。因此,在一个特殊的处理器对话期间内,使用这个工具操作被期望临时存储在
				session
				中的会话属性。
				
						
				
						       
				
				要用到永久的
				session
				属性,例如,一个用户鉴定对象,请使用传统的
				session.setAttribute
				方法代替。可选择地,考虑使用
				org.springframework.web.context.request.W
ebRequest
				接口的属性管理功能。
				
						
				
						6
				
				
						、
				
				
						Spring2.5
				
				
						新加的
				
				
						schema tag
				
				
						。
				
				
						
								
				
						       1
				)、
				Context tags 
				用来处理涉及到
				plumbing
				的
				ApplicationContext
				配置。也就是说,不是通常的对于终端用户重要的
				bean
				,而是是处理许多
				Spring
				中日常事务的更重要的
				Bean
				,例如
				BeanfactoryPostProcessor
				。下面是使
				context
				命名空间对你起作用的正确的
				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"/> 
				
						   
				
				
						这个元素通过指定的属性文件的地址,使替代标识
				
				${…}placeholders
				
						得以活动。这个元素是一个方便的机制,它通过建立一个
				
				
						
								PropertyPlaceholderConfigurer
						
				
				
						给你提供一个方便的机制;如果你需要更多的控制
				
				PropertyPlaceholderConfigurer
				
						,那么你自己建一个吧。
						
								
				<context:annotation-config/> 
				
						使
				
				Spring
				
						基础组织中的能够自动侦查
				
				bean
				
						类的各种
				
				annotations
				
						:
				
				Spring
				
						的
				
				@Required
				
						和
				
				@Autowired
				
						,还有
				
				JSR 250
				
						规范中的
				
				@PostConstruct
				
						,
				
				@PreDestroy
				
						和
				
				@Resource
				
						(如果可用的话)还有
				
				JPA
				
						的
				
				@PersistenceContext
				
						和
				
				@PersistenceUnit
				
						(如果可用的话)。作为选择,你可以选择使用单独的
				
				BeanPostProcessors
				
						来处理那些
				
				annotations
				
						。
						
								
				注意:这个元素不能激活对
				Spring
				的
				@Transactional annotation
				的处理。请使用
				<tx:annotation-driven/>
				元素来达到目的。
				
						
				<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
				
						       
				
				这个元素能够扫描并自动侦测到指定的包中的标识为
				@Components
				的类。
				
						           - 
				
						
								总结
						
						:
						
								
				petclinic
				
						是
				
				Spring
				
						组织给出的
				
				Spring
				
						使用的示例程序。
						
								
				
						       
						 
				
				
						该程序未将领域对象和其它的业务类没严格分开(没有明确的分包来标识),而且
				
				Business
				
						层和持久层更是根本混合一起,不是很好的实践,因为持久层的类,竟然是从
				
				Business
				
						层的类继承而来,比如
				
				SimpleJdbcClinic
				
						和
				
				HibernateClinic
				
						都是继承至
				
				Clinic
				
						这个核心业务的
				
				DAO
				
						类
				
				(
				
						很显然混合就是从这里开始了
				
				)
				
						。
						
								
				
						在手册中提到,该程序主要是用来展示各种的
				
				Spring
				
						数据访问策略,而仅带有极其简单的业务逻辑,所有为了开发效率将业务层和持久层混合一起。很显然,这里如果我们改变业务方法的话,就需要几乎修改所有的持久化类了。
						
								
				
						我想更好的方式是将持久类对象
				
				Bean
				
						注入到业务类中。因为组合永远优于继承,并且如果使用
				
				Spring
				
						进行依赖注入的话会更优良。
						
								
				
						使用
				
				Spring
				
						的
				
				MVC
				
						框架,这是一个很优良的框架,比
				
				Struts1.X
				
						要强很多。
						
								
				
						使用了
				
				Spring
				
						的
				
				JMX
				
						支持
				
				API
				
						,
				
				JMX
				
						是一个基于
				
				RMI
				
						和
				
				JNDI
				
						的
				
				Java
				
						管理扩展
				
				API
				
						。
						
								
				
						使用了
				
				Spring
				
						的声明式事务管理
				
				API
				
						。
						
								
				
						使用
				
				apache
				
						的
				
				DBCP
				
						数据库连接池技术。
						
								
				
						在
				
				petclinic2.5
				
						版中,使用了
				
				annotation
				
						方式进行各种
				
				Spring
				
						配置。
				
				Annotation
				
						方式虽然提高了学习成本,但是无疑是比描述文档更优的策略,因为它减少了程序员的编写描述文件成本,而且能提供编译器的检查,程序员不用再去编写可能使我们头脑炸掉的
				
				XML
				
						描述文档。
						
								
				Spring
				
						的
				
				AOP
				
						支持,虽然这个程序中使用了几个很无聊的切面。
						
								
				
						
				
						
                    
                
                
            
        
浙公网安备 33010602011771号