首页 > 代码库 > 基于注解的SSH将配置精简到极致(1)

基于注解的SSH将配置精简到极致(1)

很早之前就想写一篇关于SSH整合的博客了,但是一直觉得使用SSH的时候那么多的配置文件,严重破坏了我们代码整体性,比如你要看两个实体的关系还得对照*.hbm.xml文件,要屡清一个Action可能需要对照applicationContext*.xml和struts*.xml文件。总之过多的配置文件坏破坏代码的整体性,会打乱代码的连续性,因为很多情况下你需要一边看Java代码,一边看xml的配置,采用注解就能很好的解决这个问题。


当然,即使采用注解的方式,也不能完全的丢掉配置文件,因为配置文件是程序的入口,是基础。服务器启动最先加载web.xml文件,读取其中的配置信息,将程序运行所需要的信息进行初始化。因为是整合SSH,所以web.xml文件中需要配置Spring以及Struts的信息,同时Spring跟Struts也需要进行一些基本的配置。


使用注解的方式,配置文件最少可以精简到三个,web.xml、applicationContext.xml和struts.xml。Hibernate可以完全交给Spring来管理,这样连hibernate.cfg.xml也省了。下面就一起看看这些基本的配置吧!


web.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  3. xmlns="http://java.sun.com/xml/ns/javaee"   
  4. xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
  5. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="SSH" version="2.5">  
  6.   <display-name>ssh</display-name>  
  7.   <welcome-file-list>  
  8.     <welcome-file>addUser.jsp</welcome-file>  
  9.   </welcome-file-list>  
  10.     
  11.   <!-- 配置Spring的监听器,用于初始化ApplicationContext对象 -->  
  12.   <listener>  
  13.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  14.   </listener>  
  15.   <context-param>  
  16.     <param-name>contextConfigLocation</param-name>  
  17.     <param-value>classpath:applicationContext*.xml</param-value>  
  18.   </context-param>  
  19.     
  20.   <!-- struts2 的配置 -->  
  21.   <filter>  
  22.     <filter-name>struts2</filter-name>  
  23.         <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  24.     <init-param>  
  25.       <param-name>filterConfig</param-name>  
  26.       <param-value>classpath:struts.xml</param-value>  
  27.     </init-param>  
  28.       
  29.     <!-- 自动扫描action -->  
  30.     <init-param>  
  31.       <param-name>actionPackages</param-name>  
  32.       <param-value>com.ssh</param-value>  
  33.     </init-param>  
  34.   </filter>  
  35.     
  36.   <filter-mapping>  
  37.     <filter-name>struts2</filter-name>  
  38.     <url-pattern>/*</url-pattern>  
  39.   </filter-mapping>  
  40. </web-app>  


web.xml中包含了Spring和struts的基本配置,自动扫描Action的配置就是告诉tomcat,我要使用注解来配置struts。


applicationContext.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>      
  2. <beans xmlns="http://www.springframework.org/schema/beans"      
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"      
  4.     xmlns:tx="http://www.springframework.org/schema/tx"      
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd      
  6.                 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd      
  7.                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">      
  8.     
  9.     <!-- 自动扫描与装配bean -->      
  10.     <context:component-scan base-package="com.tgb.ssh"></context:component-scan>      
  11.         
  12.     <!-- dbcp配置 -->    
  13.     <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">      
  14.         <property name="driverClassName">    
  15.             <value>com.mysql.jdbc.Driver</value>    
  16.         </property>    
  17.         <property name="url">    
  18.             <value>jdbc:mysql://127.0.0.1:3307/ssh</value>    
  19.         </property>    
  20.         <property name="username">    
  21.             <value>root</value>    
  22.         </property>    
  23.         <property name="password">    
  24.             <value>123456</value>    
  25.         </property>    
  26.     </bean>    
  27.             
  28.     <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">    
  29.         <property name="dataSource">    
  30.             <ref local="dataSource" />    
  31.         </property>    
  32.         <property name="hibernateProperties">    
  33.             <props>    
  34.                 <!--配置Hibernate的方言-->    
  35.                 <prop key="hibernate.dialect">    
  36.                  org.hibernate.dialect.MySQLDialect    
  37.                 </prop>                    
  38.                 <prop key="hibernate.hbm2ddl.auto">update</prop>    
  39.                     
  40.                 <!--格式化输出sql语句-->    
  41.                 <prop key="hibernate.show_sql">true</prop>    
  42.                 <prop key="hibernate.format_sql">true</prop>      
  43.                 <prop key="hibernate.use_sql_comments">false</prop>      
  44.             </props>    
  45.         </property>    
  46.             
  47.         <!--自动扫描实体 -->    
  48.         <property name="packagesToScan"  value="com.tgb.ssh.model" />    
  49.     </bean>    
  50.         
  51.     <!-- 用注解来实现事务管理 -->    
  52.     <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">    
  53.         <property name="sessionFactory" ref="sessionFactory"></property>          
  54.     </bean>    
  55.     <tx:annotation-driven transaction-manager="txManager"/>    
  56.         
  57. </beans>   



applicationContext.xml里配置了数据库连接的基本信息(对hibernate的管理),还有对所有bean的自动装配管理和事务的管理。

struts.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <!DOCTYPE struts PUBLIC    
  3. "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    
  4. "http://struts.apache.org/dtds/struts-2.3.dtd">     
  5.         
  6. <struts>    
  7.   
  8.     <!-- 开启使用开发模式,详细错误提示 -->    
  9.     <constant name="struts.devMode" value="true" />    
  10.     <!-- 将对象交给spring管理 -->    
  11.     <constant name="struts.objectFactory" value="spring" />    
  12.     <!-- 指定资源编码类型 -->    
  13.     <constant name="struts.i18n.encoding" value="UTF-8" />     
  14.     <!-- 指定每次请求到达,重新加载资源文件 -->    
  15.     <constant name="struts.i18n.reload" value="false" />    
  16.     <!-- 指定每次配置文件更改后,自动重新加载 -->    
  17.     <constant name="struts.configuration.xml.reload" value="false" />    
  18.     <!-- 默认后缀名 -->    
  19.     <constant name="struts.action.extension" value="action," />       
  20.     
  21. </struts>    



struts.xml里配置了一些struts的基本参数,并告诉容器用Spring来管理自己。


到这里一个基本的SSH的配置就算完成了,配置很简单,而且每一项配置都有说明,相信理解上不会有什么问题。基础的配置就这么多,下面就是我们的注解发挥作用的时候了。


userAdd.jsp

[html] view plaincopy
  1. <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  3. <html>  
  4.   <head>  
  5.     <title>添加用户</title>  
  6.   </head>  
  7.     
  8.   <body>  
  9.       <form method="post" action="addUser">  
  10.         用户名:<input type="text" name="user.name"><br>  
  11.         密码:<input type="password" name="user.password"><br>          
  12.         <input type="submit" value="登录"/>  
  13.     </form>      
  14.   </body>  
  15. </html>  

用户添加页面,将用户信息提交给UserAction。


UserAction

[java] view plaincopy
  1. package com.tgb.ssh.action;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.apache.struts2.convention.annotation.Action;  
  6. import org.apache.struts2.convention.annotation.Result;  
  7. import org.apache.struts2.convention.annotation.Results;  
  8.   
  9. import com.opensymphony.xwork2.ActionSupport;  
  10. import com.tgb.ssh.model.User;  
  11. import com.tgb.ssh.service.UserManager;  
  12.   
  13.   
  14. @Results( { @Result(name="success",location="/success.jsp"),  
  15.         @Result(name="failure",location="/failure.jsp") })   
  16. public class UserAction extends ActionSupport {  
  17.     @Resource  
  18.     private UserManager userManager;  
  19.     private User user;  
  20.       
  21.     @Action(value=http://www.mamicode.com/"addUser")  
  22.     public String addUser() {  
  23.         try {  
  24.             userManager.addUser(user);          
  25.         } catch (Exception e) {  
  26.             e.printStackTrace();  
  27.             return "failure";  
  28.         }  
  29.         return "success";  
  30.           
  31.     }      
  32.   
  33.     public User getUser() {  
  34.         return user;  
  35.     }  
  36.     public void setUser(User user) {  
  37.         this.user = user;  
  38.     }  
  39.       
  40.       
  41. }  

UserAction通过注解配置Action的名字和返回的页面,通过@Resource活动Spring注入的UserManager对象,然后进行相应的操作。Action里还有@Namespace、@InterceptorRef等很多注解可以用,根据自己需要选择吧。


UserManager

[java] view plaincopy
  1. package com.tgb.ssh.service;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.springframework.stereotype.Service;  
  6. import org.springframework.transaction.annotation.Transactional;  
  7.   
  8. import com.tgb.ssh.dao.UserDao;  
  9. import com.tgb.ssh.model.User;  
  10.   
  11. @Service  
  12. @Transactional  
  13. public class UserManager {  
  14.     @Resource  
  15.     UserDao userDao;  
  16.       
  17.     public void addUser(User user) {  
  18.         userDao.addUser(user);  
  19.     }  
  20.       
  21. }  

UserManager通过@Service自动装配到Spring的容器,为其他组件提供服务;通过@Transactional进行事务的管理;通过@Resource注入UserDao对象。


UserDao

[java] view plaincopy
  1. package com.tgb.ssh.dao;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.hibernate.Session;  
  6. import org.hibernate.SessionFactory;  
  7. import org.hibernate.Transaction;  
  8. import org.springframework.orm.hibernate4.HibernateTemplate;  
  9. import org.springframework.stereotype.Repository;  
  10.   
  11. import com.tgb.ssh.model.User;  
  12.   
  13. @Repository  
  14. public class UserDao {  
  15.     @Resource(name="sessionFactory")   
  16.     private SessionFactory sessionFactory;  
  17.       
  18.     public void addUser(User user ) {  
  19.         Session session = sessionFactory.getCurrentSession();  
  20.         session.save(user);  
  21.     }  
  22.   
  23. }  

UserDao通过@Repository自动装配到Spring的容器,通过@Resource获得Sessionfactory,将User对象持久化。


User

[java] view plaincopy
  1. package com.tgb.ssh.model;  
  2.   
  3. import javax.persistence.Entity;  
  4. import javax.persistence.GeneratedValue;  
  5. import javax.persistence.GenerationType;  
  6. import javax.persistence.Id;  
  7.   
  8.   
  9. @Entity(name="t_user")  
  10. public class User {  
  11.     @Id  
  12.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  13.     private int id;  
  14.     private String name;  
  15.     private String password;      
  16.        
  17.       
  18.     public int getId() {  
  19.         return id;  
  20.     }  
  21.   
  22.     public void setId(int id) {  
  23.         this.id = id;  
  24.     }  
  25.   
  26.     public String getName() {  
  27.         return name;  
  28.     }  
  29.       
  30.     public void setName(String name) {  
  31.         this.name = name;  
  32.     }  
  33.     public String getPassword() {  
  34.         return password;  
  35.     }  
  36.     public void setPassword(String password) {  
  37.         this.password = password;  
  38.     }  
  39. }  
User通过@Entity将实体类映射到数据库,生成t_user表,通过@Id定义表的Id,通过@GenerateValue定义Id的生成策略。


好了,到此为止,基于注解的SSH就算是搭建完成了。基础的搭建已经使注解简洁的优势初现端倪,随着开发的进行,代码不断地增加,其简洁的风格相比传统配置文件的方式会更加明显。因为如果采用配置文件的方式,每增加一个Action都需要在struts.xml和applicationContext.xml文件增加一段代码;每多一个实体,也需要多一个*.hbm.xml文件。配置文件泛滥是一件让人头疼的事情。


注解好处多多,而且也越来越流行,但配置文件也并不是一无是处。注解有注解的好,配置文件有配置文件的妙。还是那句话,技术没有好坏之分,只有合适不合适之别。一味的追求技术的好与坏不是明智之举,选择一个合适的才是真正的设计之道。本文主旨不在于告诉你注解比配置文件好,而是向大家介绍另一种方式,可以多一种选择,也许你会找到一种更合适的方式。