1.前言
之前都是在現有框架下進行寫代碼或者總是看一些別人的架構,總會眼高手低。於是打算自己完整的走一遍流程,同時把所遇到的問題,思考的問題記下來,供大家參考。由於是工作年限不高,屬於新手,不足之處還請各位大牛指正。
項目選用Spring為基礎框架,由於目前項目中采用的是Hibernate(在多表關聯查詢方面以及復雜的統計計算方面,同時要兼顧性能的時候吃了不少苦頭),所以這里采取Mybatis做持久化框架(沒實戰搭建過),Spring MVC框架。在權限控制方面現有項目中采用的是shiro(為了學習,這里使用spring security)。其他的細節問題會在下面各小節中敘述。
另說明一點的是操作系統是mac。
github項目源碼在https://github.com/sjlian/sjlian 歡迎clone並提出意見。
2. 創建mvn項目、完善目錄結構
首先安裝和配置環境,主要包括jdk、mysql、maven等,其他如redis、nginx、ActiveMQ等在初始版本還暫時沒上傳和使用。這些入門知識不再贅述。
在idea上新建一個mvn項目,然后有一個create from archetype,里面有很多選項,於是有個疑問到底用哪個呢?遂逐一查看名字,看到mvn-archetypr-webapp,聽名字就覺得和自己的預期是一樣的啊,於是果斷選擇。期間又試了下其他的各個archetype,發現這這是一個模板,可以根據自己需要選擇,也可以默認缺省的。這里附上mvn官方標准化的目錄結構如下圖:

一個好的程序員都善於用命令行的方式解決問題,於是思考怎么用mvn命令行創建項目。最簡單的方式就是mvn archetype:generate,這個命令是默認的 archetype,如果需要生成特定模板的項目呢?從maven的Repository里查找arche types發現有幾百個,我們平時用的也就那么幾個,由於太多就變得很不方便起來,於是搜索資料,查到 http://maven.40175.n5.nabble.com/archetype-catalog-xml-location-archetype-crawl-versus-archetype-generate-td113741.html

完善目錄結構大致如上圖(是demo最終版本),這個時候只需要在java目錄下新建幾個包,進行分層,使項目結構變得清晰。
common主要放置一些通用的非工具類,如exception相關,結果相關,攔截器,servlet,VO類等。
Controller、DAO、model、service顧名思義,分別是控制層、持久層、數據模型層、業務處理層。
util主要存放各種工具類,例如字符串、時間、poi、郵件、ip等
resource主要是配置文件,包括spring相關配置文件、mybatis配置文件、mybatis映射文件、日志配置文件等
web-inf下最重要是web.xml,作為啟動需要首先加載的文件,引入其他配置文件、配置listener、servlet、filter、Interceptor等。
其他是和前端相關文件
test是和測試相關。
建好以上目錄,開始進入正題。
3. 引入Spring
3.1 web.xml
web程序啟動會去讀取它的配置文件 web.xml,首先需要配置web.xml,添加上spring的監聽器、spring mvc的Servlet。
ContextLoaderListener 它實現了ServletContextListener這個接口,在web.xml配置這個監聽器,啟動容器時,就會默認執行它實現的方法。在ContextLoaderListener中關聯了ContextLoader這個類,所以整個加載配置過程由ContextLoader來完成。
RequestContextListener implements ServletRequestListener,監聽用戶的請求,用於日志系統,不是必需的。
IntrospectorCleanupListener監聽器主要用於解決java.beans.Introspector導致的內存泄漏的問題(Quartz,Struts),如果沒有struts和quartz不是必需的。
Spring MVC 以自啟動servlet的形式加載,同時引入相關spring/spring-mvc.xml配置文件。文件路徑classpath:開頭,從classpath加載,否則嘗試URL,如果失敗,調用 getResourceByPath。

此外,為了防止中文亂碼,需要encodingFilter;設置session超時時間、用戶自定義Listener、servlet、filter、interceptor等。
3.2 pom.xml
直接把Listener復制到xml中,會發現ide並不識別,是因為相關依賴還沒有導入項目中的原因。 在pom.xml中引入spring相關,引入的時候會發現depency有一些屬性值,如groupId、artifactId等,對於開源項目來說,這兩項是固定的,按照文檔導入即可,version是版本號,為了便於升級和管理,建議版本號統一配置。


有時候會發現還有scope屬性,如junit的scope屬性值是test用於test任務時使用;compile(default)編譯時使用;provided類似於編譯但支持你期待jdk或者容器提供,類似於classpath;runtime在執行時需要使用;system需要外在提供相應得元素。通過systemPath來取得;
有時候會遇到依賴沖突,例如同時導入了A、B包,但是A包又引用了B包,當版本不一致時就會沖突,解決方式是mvn dependency:tree 分析沖突的包,然后在相應的A包中配置<exclusions> 把B包排除在外。
如果想引入本地依賴,1、使用scope system和systemPath指向依賴包;2、mvn install命令進行安裝並配置group和artifact,然后直接引入。3、建立pom依賴關系。POM關系主要為依賴,繼承,合成,在這個小項目中用不到,且不是重點,故略去。
3.3 其他配置文件
spring-mvc.xml主要配置如下。
1.開啟注解模式就可以使用注解方式@ResponseBody,@RequestMapping等。
2.對於靜態的jpg、css等不需要通過mvc。
3.添加前后綴,注意路徑。
4.掃描controller的bean,讓spring知道哪些是controller(@Controller)。

如果需要對返回值進行json統一化處理,在這里可以引入json處理,如fastJson、jackson等。fastJson輕量級速度快,但是支持有輕微漏洞,jackson靈活性好,但是比較笨重,這里選用的是fastJson,配置如下。

如果需要上傳文件,還需要配置文件上傳,如下:

web.xml中引入配置文件,該配置文件作為spring基礎配置文件,再引入其他文件。

spring.xml中配置如下,這里注入service、引入mybatis、security配置,配置事務管理、開啟聲明是式事務(@transtraction)。

4.引入Mybatis
4.1 文件配置
在spring.xml中引入了spring-mybatis.xml,用於Mybatis和spring的整合配置。同時pom.xml中引入相關依賴。
1.配置數據源,數據庫連接池,可以選擇的有c3p0、druid、dbcp、HikariCP等,這里選擇阿里的開源框架druid,配置如下。url、username等建議寫在property文件中。

2. 配置sessionFactory, 引入mybatis全局配置文件、entity使用別名,掃描mapping.xml
3. 配置DAO接口,注入Srping容器中。

4. 配置mybatis-config.xml

5. mvc層搭建
5.1 DAO層
由於mybatis不支持jpa,不能由實體映射數據表,所以需要自己新建數據表和數據實體。
可以使用工具由數據表生成數據實體。
數據實體在model目錄下。
映射文件在resources/mapper下,如果設置了自動轉換對象關系名,這里不在需要配置對象關系的名稱映射,但是需要注意命名的書寫,注意namespace一致。
DAO接口文件在dao目錄下,DAO實現在mapper的xml中,select/update id和接口中的方法對應即可。在service注入dao的時候會提示無法注入的錯誤,忽略即可。
5.2 service層
在service下定義接口,在service/impl/下定義實現,加上@Service注解
5.3 Controller層
在Controller目錄下,可以實現封裝好的json數據、string連接、ModelAndView。
6. DEMO完善
5.1 加入日志系統
log4j,配置log4j.properties。如下

然后可以利用filter做請求參數日志輸出。
利用aop做一些其他日志輸入。
5.2 封裝統一化返回值
前后端json數據交互,自定義ResponseResult,包括頭信息(狀態碼,錯誤信息說明,異常),數據信息。
異常通過@ControllerAdvice 捕獲到然后封裝處理返回給前端,不至於頁面報錯,或者自定義異常彈窗。
5.3 工具類准備
各種工具類提取
5.4 權限控制
使用spring security,目前還是半成品,以后完善。
5.5 其他處理

