1. 程式人生 > >2018第一作,JFDF快速開發框架的橫空出世

2018第一作,JFDF快速開發框架的橫空出世


前言
寫在前面的話,致每一位讀者!
任何事物的誕生總有她的必然性和偶然性,就如牛頓當年坐在樹下被水果砸中頭後發明了萬有引力,是坐下樹下的偶然,也是歷史推動的必然。
JFDF也不例外,作為一個遊走在職場數十年的老兵程式設計師,出於對程式事業的尊敬也出於對程式設計師職業的熱愛,讓我總想在我的當打之年留下點什麼。
回顧過去,縱使開始這個專案的理由有上千種,但由於本人天生慵懶也導致了專案的胎死腹中。然而由於吃雞外掛的泛濫,讓我們這些循規蹈矩的首批玩家完全沒有一點生存空間,要麼遇見閃電俠見光死,要麼就是喝一梭子彈立馬變郵包(ps:本人吃雞賬號"包發虎",歡迎組隊吃雞!!!)。沒有了精神食糧的我決定痛定思痛,開始做一些有意義的事情,以尋找靈魂的依偎(逼格就是這樣出來的,哈哈!!!)。
其實對我來說做這樣的工作不是第一次,肯定也不會是最後一次,但每次腦海中的想法總會有千絲萬縷的差異。依稀記得第一次動手做研發框架,總想憑藉這自己的能力力挽狂瀾,為這個世界的改變能做點貢獻,但事實總是那麼的無情。當我捲起袖子管,徒手寫了無數的程式碼、設計模式、工具類等等以後,卻發現我引以為豪的優秀作品缺無人問津,Every body還是按照自己的習慣該幹嘛就幹嘛,世界還是保持著原樣,地球還是那樣的在自轉著。總結了那麼多的歷史經驗,我準備在儘量不改變的大家開發習慣的前提下,來完成本開源專案。簡單說我不是什麼發明家,我只是程式碼的搬運工。

JFDF介紹
JFDF的全稱是JAVA Fast Development Framework,即JAVA快速開發框架。

JFDF快速構建應用系統: JFDF可以幫助大家快速投入到web專案的開發當中,從而避免了許多程式開發初期階段不必要的麻煩,諸如各種開源技術的整合、開發規範、專案結構、訪問許可權控制、使用者角色管理、系統選單管理、必要資料的初始化等等。相信每一個獨立研發過產品的攻城獅來說,都經歷過以上的這些工作,繁瑣、枯燥、乏味,每天伴隨著的是數不清的除錯和問題以及有相容性錯誤,久而久之讓我們不得不懷疑人生,常常認為自己已然成為了一個問題青年。總之,JFDF建立的初衷是想能夠幫助你迅速構建起你的業務系統,讓每一位開發人員的視角聚焦在業務功能上,從而避免不必要的麻煩。
JFDF是一套嚴格的開發規範: 曾幾何時的我,初出茅廬涉世未深。我顯然不是什麼明星學霸也不是嘴裡喊著金鑰匙出生的明日之星,犯過所有程式猿所犯過的所有錯誤,也經歷過每一位新人程式猿的惶恐不安。有時為了緬懷過去,會不經意間翻開曾經年少時做過的專案,看著一坨坨的程式碼片段,滿目瘡痍,不忍直視。可能系統沒有崩潰是上天對我的眷顧,但是讓我再去拾起它繼續後面的工作那絕對是打死我一百個不願意。然而,本著自己的一份執著,在歷史的某個時間點上,開始對自己過去犯過的過錯進行總結,簡單說好的專案必須要有嚴格的管理規範,逼格高一點的說法就是,“要讓你的程式碼會說話”,可能這也就是所謂的Code as data。當然,歸根結底好的開發規範能幫助我們提升我們的專案質量、確保專案整體的可維護性,等等等等(此處省略一萬字...)。這也是我做這個開源專案的另一個初衷。
JFDF能幫我們提升工作效率: 記得曾經的面試經常會遇到這麼一些問題:你以前的團隊有多少人?你最多負責過幾個人的團隊?你能管理幾十人的團隊嗎?等等等等。。這些問題讓我不得不懷疑,我們日以繼夜,年復一年不斷的努力工作、努力學習,我們所積累的知識和學識僅僅是為了面對這麼一個以量取勝的數字遊戲嗎?顯然不是。我覺問題的根本還是我們應該怎麼樣來提高我們的工作效率。然後聚焦到程式設計師這個職業上就是,我們怎麼樣提高我們的研發效率。不知從何時開始,我們國內養成了這樣一種習慣,即所謂的前後分離,暫且不管是真分還是假分,反正就是前後分離。當然,概念的本質是美好的,但我相信每一位實際操作過的攻城獅肯定遇到了各種對接的煩惱,輕則謾罵撕逼、重則拳腳相加,讓程式猿這麼一個老實本分的職業披上了一層危險色彩。當然,回到如何提升研發效率這個課題上來說的話,這是一門科學、一門學科,會有各種各樣的權威解釋,然而,作為我片面的認為,全棧就是提升產品研發效率的一種方式。正所謂你說服不了別人,但是你可以輕易的說服你自己。當你一個人面對全棧的所有問題,也沒有了其他讓你說服的人,那順其自然的你只能說服你自己了。然而,JFDF正是這樣一套全棧框架。(ps:關於全棧提升效率的話題,這裡再次強調,只是代表個人片面的理解)。
JFDF未來的暢想: 今天是2018年1月份,在我用了一個多月的閒暇時間的努力後,JFDF的1.0.0版本終於可以見天日了。當然,對於這樣一個初生的“嬰兒”來說目前的功能還很薄弱,但是正是這樣一個初生的“嬰兒”,她未來的發展潛力也是無限的。她就好比是平行時空中的一個奇點,會迎來屬於她自己的大爆炸,從而孕育出宇宙和生命。未來我希望有更多的業務應用基於JFDF來構建,同時在構建的過程中不斷的反饋不斷完善,也為了我們的開源事業儘自己的一份微薄之力。
作者
甜心的超級奶爸 

[email protected] (我是一名程式猿,我為程式猿代言!!!)
JFDF當前的主要功能
系統必要資料的初始化: JFDF內建了一個XML的配置檔案,首次執行系統時,只需寫入配置即可完成所有的資料初始化工作。
系統登入:

系統首頁:

使用者管理: 
角色管理: 
選單管理: 
資源管理: 
必要的依賴
作為一名Spring社群的一名死忠粉,JFDF的核心技術也主要都是圍繞著以Spring技術來構建的。

前端技術
依賴管理 Bower
核心技術 jquery 3.2.1 為了上手方便,前端核心技術採用jquery直接操作DOM樹的方式,簡單粗暴,堪稱暴力美學。當然後續我會逐步退出Angular、Vue、React的版本。
Bootstrap 3.3.7
頁面樣式 Admin-lte 3.2.1
樹 zTree 3.5.29
表單驗證 formvalidation.io 0.0.3
資料表格 bootstrap-table 1.11.1
過度效果 jquery-loading 1.2.0
提示框 sweetalert 2.0.7
圖形報表 flotjs morrisjs
後端技術
JDK版本 JDK版本必須>=1.8,可能是作為處女座的程式設計師的天性使然,我對於程式程式碼的要求還是有潔癖的,能簡潔的儘量簡潔,能少寫一行的絕不會寫第二行。所以過多的依賴了JDK1.8裡面的新特性。
依賴管理 Apache Maven 3.5.0
資料庫 MSQL 5.7.17,反正我是在這個版本下開發的,其它版本大家可做嘗試。
啟動方式 Spring Boot
持久化層 Spring JPA
系統許可權 Spring Security
模板引擎 Freemark 為了不依賴與容器,保證專案的獨立啟動,且由於Volicty的停止維護以及Thymeleaf的不友好,所以選擇了Freemarker
介面文件 Springfox & Swagger2
資料校驗 Spring Validation
Json序列化 Jackson Json
資料庫連線池 Tomcat Jdbc
還有許多就不一一列舉了。。。
JFDF目錄結構
JDFD採用標準的Maven構建,目錄結構也是標準的Maven專案結構。
猶豫內容比較多,這裡我羅列了一些專案主要檔案的目錄結構,經供參考。

JFDF/                                         /**系統更目錄**/
├──assembly/
| └──bin.xml                                  /**打包配置檔案**/
├──screen/                                    /**系統截圖**/
├──src/                          
| ├──main/                                    /**原始碼目錄**/
| | ├──java/                                  /**java原始碼**/
| | | ├──com.jhonelee.jfdf.Application.java   /**專案啟動檔案**/
| | | └──com.jhonelee.jfdf.conf.**            /**Java config**/
| | └──resource/
| |   ├──public/                              /**靜態資源目錄**/
| |   ├──templates/                           /**freemark模板檔案**/
| |   ├──application.preperties               /**spring boot配置檔案**/
| |   ├──messages.preperties                  /**本地化檔案**/
| |   └──resource.xml                         /**系統初始化檔案**/
| └──test/                                    /**單元測試程式碼目錄**/
├──target/                                    /**編譯後的可執行檔案**/
├──.gitingore                                 /**git的ingore檔案**/
├──pom.xml                                    /**maven配置檔案**/
└──README.md
JFDF配置說明
資料庫配置
由於JFDF的資料持久化層採用了Spring JPA(關於JPA的使用,請自行翻閱相關資料,這裡不做贅述。),那麼我們可以很方便的在系統初始化的時候,根據我們定義的業務實體類自行建立資料庫表、關聯表、主鍵、外檢、索引等。這種方便的操作完全符合我這種懶人的習慣。

預設資料庫配置

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jfdf?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.tomcat.max-active=100
spring.datasource.tomcat.initial-size=4
spring.datasource.tomcat.max-idle=10
spring.datasource.tomcat.min-idle=10
spring.datasource.tomcat.jdbc-interceptors=ConnectionState;StatementFinalizer;StatementDecoratorInterceptor;ResetAbandonedTimer;SlowQueryReport(threshold=500);SlowQueryReportJmx(notifyPool=false)
spring.datasource.tomcat.validation-query=select CURRENT_USER
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.default-auto-commit=false
可以在application.properties中修改。

初始化配置檔案
resource.xml JFDF提供了一個系統必要資料的初始化檔案,包括系統訪問資源初始化和系統選單的初始化。JFDF在首次啟動時會讀解析resource.xml,將相關配置資料載入到系統中。內容如下:

<resource name="JFDF" code="JFDF" type="SYSTEM" iconType="ICON" iconPath="fa-sitemap">
    <resource name="首頁" code="index" type="MENU" url="/index/page" httpMethod="GET" iconType="ICON" iconPath="fa-dashboard">
        <resource name="首頁頁面" code="index_page" type="RESOURCE" url="/index/page" httpMethod="GET" />
    </resource>
    <resource name="系統管理" code="system_management" type="MENU" httpMethod="GET" iconType="ICON" iconPath="fa-cog">
        <resource name="使用者管理" code="user_management" type="MENU" url="/user/page" httpMethod="GET" iconType="ICON" iconPath="fa-user">
            <resource name="使用者頁面" code="user_page" type="RESOURCE" url="/user/page" httpMethod="GET" />
            <resource name="使用者新增" code="user_create" type="RESOURCE" url="/user" httpMethod="POST" />
            <resource name="使用者詳情" code="user_read" type="RESOURCE" url="/user/{id}" httpMethod="GET" />
            <resource name="使用者編輯" code="user_update" type="RESOURCE" url="/user/{id}" httpMethod="PUT" />
            <resource name="使用者刪除" code="user_delete" type="RESOURCE" url="/user/{id}" httpMethod="DELETE" />
            <resource name="使用者查詢" code="user_find" type="RESOURCE" url="/users" httpMethod="GET" />
            <resource name="使用者校驗" code="user_validation" type="RESOURCE" url="/user/validation" httpMethod="GET" />
            <resource name="使用者角色查詢校驗" code="user_roles_find" type="RESOURCE" url="/roles" httpMethod="GET" />
        </resource>
        <resource name="角色管理" code="role_management" type="MENU" url="/role/page" httpMethod="GET" iconType="ICON" iconPath="fa-group">
            <resource name="角色頁面" code="role_page" type="RESOURCE" url="/role/page" httpMethod="GET" />
            <resource name="角色新增" code="role_create" type="RESOURCE" url="/role" httpMethod="POST" />
            <resource name="角色詳情" code="role_read" type="RESOURCE" url="/role/{id}" httpMethod="GET" />
            <resource name="角色編輯" code="role_update" type="RESOURCE" url="/role/{id}" httpMethod="PUT" />
            <resource name="角色刪除" code="role_delete" type="RESOURCE" url="/role/{id}" httpMethod="DELETE" />
            <resource name="角色查詢" code="role_find" type="RESOURCE" url="/roles" httpMethod="GET" />
            <resource name="角色校驗" code="role_validation" type="RESOURCE" url="/role/validation" httpMethod="GET" />
            <resource name="角色資源數載入" code="role_menu_load" type="RESOURCE" url="/role/menu/children" httpMethod="GET" />
            <resource name="角色授權" code="role_menu_load" type="RESOURCE" url="/role/{roleId}/resource" httpMethod="PUT" />
        </resource>
        <resource name="選單管理" code="menu_management" type="MENU" url="/menu/page" httpMethod="GET" iconType="ICON" iconPath="fa-bars">
            <resource name="選單頁面" code="menu_page" type="RESOURCE" url="/menu/page" httpMethod="GET" />
            <resource name="選單載入" code="menu_child_load" type="RESOURCE" url="/menu/children" httpMethod="GET" />
            <resource name="選單新增" code="menu_create" type="RESOURCE" url="/menu" httpMethod="POST" />
            <resource name="選單詳情" code="menu_read" type="RESOURCE" url="/menu/{id}" httpMethod="GET" />
            <resource name="選單編輯" code="menu_update" type="RESOURCE" url="/menu/{id}" httpMethod="PUT" />
            <resource name="選單刪除" code="menu_delete" type="RESOURCE" url="/menu/{id}" httpMethod="DELETE" />
            <resource name="選單查詢" code="menu_find" type="RESOURCE" url="/menus" httpMethod="GET" />
            <resource name="已選中資源查詢" code="menu_find" type="RESOURCE" url="/menu/{menuId}/selectedMenus" httpMethod="GET" />
            <resource name="資源更新" code="menu_resource_update" type="RESOURCE" url="/menu/{menuId}/selectedMenus" httpMethod="PUT" />
        </resource>
        <resource name="資源管理" code="resource_management" type="MENU" url="/resource/page" httpMethod="GET" iconType="ICON" iconPath="fa-tree">
            <resource name="資源頁面" code="resource_page" type="RESOURCE" url="/resource/page" httpMethod="GET" />
            <resource name="資源校驗" code="resource_validation" type="RESOURCE" url="/resource/validation" httpMethod="GET" />
            <resource name="資源新增" code="resource_create" type="RESOURCE" url="/resource" httpMethod="POST" />
            <resource name="資源詳情" code="resource_read" type="RESOURCE" url="/resource/{id}" httpMethod="GET" />
            <resource name="資源編輯" code="resource_update" type="RESOURCE" url="/resource/{id}" httpMethod="PUT" />
            <resource name="資源刪除" code="resource_delete" type="RESOURCE" url="/resource/{id}" httpMethod="DELETE" />
            <resource name="資源查詢" code="resource_find" type="RESOURCE" url="/resources" httpMethod="GET" />
        </resource>
        <resource name="許可權管理" code="authority_management" type="MENU" url="/authority/page" httpMethod="GET" iconType="ICON" iconPath="fa-user-secret">
            <resource name="許可權頁面" code="authority_page" type="RESOURCE" url="/authority/page" httpMethod="GET" />
            <resource name="許可權查詢" code="authority_find" type="RESOURCE" url="/authorities" httpMethod="GET" />
        </resource>
    </resource>
</resource>
注意這裡的type屬性,type=SYSTEM|MENU|RESOURCE,SYSTEM代表系統,MENU代表導航選單,RESOURCE代表訪問資源即系統功能。當然有人可能會問這裡為什麼會引入SYSTEM的概念,我是為了後面OATH2的開發做準備。

預設的系統管理員賬號
系統初始化成功後會提供一個預設的管理員
使用者名稱:admin
密碼:password
該賬號擁有系統中的最高許可權,可以訪問所有功能。另外,如需更多其它賬號,請使用系統功能進行新增。

JFDF開發手冊
JFDF的半前後分離模式
要說JFDF的開發模式,其實在我開始這個專案之前就一直在考慮,是採用前後分離呢,還是採用mvc,是採用MVC呢,還是採用前後分離,我真的想了很久很久,想的腳進腦之,腦袋爆炸貌似也沒有一個很好的結果,索性不想了,先魯碼再說。如果硬是要給JDFD的開發模式定個性的話,我只能說是半前後分離模式。那什麼是半前後分離模式呢,就好比我們日常生活中的汽車,大家都知道汽車有自動擋汽車和手動擋汽車,當然也有介於它們之間的手自一體的模式,其承載了部分手動擋的特性和自動擋的特性而形成了自己特有的模式,JFDF的半前後分離模式也是這麼一種情況。
JFDF的頁面跳轉路由採用Srping MVC和Freemarker來實現,直觀一點來說的話,也就是導航選單中的每一個導航項即對應一個單頁面的應用(熟悉Angular的同學應該非常熟悉什麼叫單頁面應用),這個過程採用的是Spring MVC。
當我們進入功能頁面之後能,所有的增刪改查操作都在這一個頁面完成,沒有任何頁面重新整理操作,這樣就是我們的前後分離模式。
總的來說結合起來的話就是半前後分離模式(一個笑臉)。

JFDF功能介面
說完了頁面跳轉,接著我們來說收系統介面。JFDF所有的資料介面都是採用標準的RESTFul介面來構建,介紹的時候我們就提到過,好的專案必須要有好的標準,所以所有的系統介面開發必須RESTFul,必須RESTFul,必須RESTFul,重要的事情說三遍(關於什麼是RESTFul介面,自己翻閱文件),別問我為什麼那麼霸道,我有我後面的考慮,暫且保密。

介面文件訪問地址
http://localhost:8080/swagger.html

RESTFul介面樣例
查詢介面
請求: HTTPMETHOD=GET
http://localhost:8080/[EntityName]?page=[pageNumber]&size=[sizeNumber]&[param1]=[value1].... 
響應:
{
 
  "content": {
      ...'json data'
  },
  "first": true,
  "last": true,
  "number": 0,
  "numberOfElements": 0,
  "size": 0,
  "sort": {},
  "totalElements": 0,
  "totalPages": 0
}
功能開發N步走!
這裡我們以使用者管理功能為例,請注意程式碼用的命名規範。

功能配置
新增功能地址在資源管理中,新增你所需要的功能訪問地址
新增到系統選單把新增的資源新增到選單中
功能授權為新功能授權
建立業務實體
package com.jhonelee.jfdf.user.entity
@Entity
@Table(name = "sys_user")
public class User implements Serializable {
    private static final long serialVersionUID = 6210408035778291012L;
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    private String username;
 
    private String password;
 
    private String email;
 
    private String mobile;
 
    private String nickname;
 
    private Boolean active = Boolean.TRUE;
}
建立Repository
package com.jhonelee.jfdf.user.repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
 
}
建立Service
package com.jhonelee.jfdf.user.service;
@Service
public class UserService {
 
}
建立Dto
package com.jhonelee.jfdf.user.dto;
public class UserDto {
    
    private Long id;
 
    private String username;
 
    private String password;
 
    private String email;
 
    private String mobile;
 
    private String nickname;
 
    private Boolean active;
}
這裡可能大家會有疑問,我們可以省去Dto,直接使用之前定義的Entity,怎麼說呢,可以也不可以。但是這時會有一個嚴重的問題,當使用了複雜型別的Entity後,系統啟動會報錯,陷入死迴圈。對於這個問題的細節,我後續會單獨開博文來分析,這裡只需要記住,資料傳輸要用Dto。

建立校驗器
package com.jhonelee.jfdf.user.validator;
@Component
public class UserDtoValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return UserDto.class.equals(clazz);
    }
    @Override
    public void validate(Object target, Errors errors) {
        ValidatorUtils.validateEmpty(errors, target, "username", "email", "mobile", "nickname");
        ValidatorUtils.validateUnique(errors, target, User.class, "id", "username");
    }
}
通過校驗器,我們可以把業務校驗邏輯從Controller中剝離出來。

建立Controller
package com.jhonelee.jfdf.user.controller;
@Controller
public class UserController {
 
}
建立頁面檔案
頁面檔案存放路徑

JFDF/
 └──main/
   └──resource/
     └──templates/
       └──user/
         └──user.ftl
建立js檔案
js檔案存放路徑

JFDF/
 └──main/
   └──resource/
     └──public/
       └──js/
         └──user/
       └──user.js
#¥%……#¥%……#¥%……
好了,開發一個功能,差不多要建立這些檔案,也確實不容易,後續我會開發一些程式碼生成功能供大家使用,具體大家可以去看程式碼。

版本
當前版本 RELEASE.1.0.0
開發計劃
這裡我會大致羅列一些我後面要做的事情,但是具體的時間我不太想排,大家也別給我太多的壓力,畢竟我是一對雙胞胎女兒的老爸。但我相信我的工作效率,我會經我最大的能力為JFDF添磚加瓦。

為JFDF新增流程管理的能力
為JFDF新增規則引擎
為JFDF新增程式碼生成器
為JFDF新增表單配置功能
為JFDF新增視覺化的頁面佈局
為JFDF新增視覺化報表配置能力
將JFDF作為微服務的中央管理平臺
將JFDF作為大資料的管理平臺
最後
霹靂啪啦寫了那麼多,我也是好久沒寫那麼多字了。反正就這麼一個東西,希望大家會喜歡,希望大家用的好、用的爽,希望用了JFDF後工作順利,心情愉悅,每天晚上,準時下班,回家吃飯。
--------------------- 
作者:甜心的超級奶爸 
來源:CSDN 
原文:https://blog.csdn.net/l13482477/article/details/78991710 
版權宣告:本文為博主原創文章,轉載請附上博文連結!