使用Gradle 構建一個SpringBoot + Spring Security + Mybatisplus的多模塊系統


## 目標

- 使用 Gradle 構建一個多模塊系統,熟悉腳本
- 搭建 SpringBoot ,Spring Security ,Mybatis子模塊,實現基本的 Hello World。可以獨立運行。

總體步驟:新建父工程(gradle) - 配置maven - 新建多個子工程(SpringBoot ,Spring Security ,Mybatis) - 修改父子的build.gradle & 父的settings.gradle  - 將無用的文件進行刪除 - 寫相關測試類 - 測試

Pre1: 建本地數據庫

 

 

 

Pre2: 把一個empty項目變成gradle項目:  gradle init build

 

 

 

Pre3: git 從分支拉取:git clone -b brachname XXX

git push指定分支:git push origin brachname

 

1 搭建父工程:父工程沒什么要求,直接new一個gradle的空工程就行。

 

父模塊建好之后,多了下面紅色框標出的東西,我們需要修改的有build.gradle(配置構建gradle項目時的一些東西,后面會細說,搭建多模塊項目,主要就是在配置各個模塊的這個文件) settings.gradle (配置父子模塊間的依賴關系)

build.grale文件詳細解釋:https://www.cnblogs.com/caesar-the-great/p/12671179.html

 

配置父模塊的build.gradle文件

  1 /*
  2  * This file was generated by the Gradle 'init' task.
  3  *
  4  * This is a general purpose Gradle build.
  5  * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds
  6  */
  7 buildscript {
  8     repositories {
  9         maven {
 10             url 'https://maven.aliyun.com/repository/gradle-plugin'
 11         }
 12     }
 13 }
 14 plugins {
 15     id 'org.springframework.boot' version '2.2.5.RELEASE' apply false
 16     id 'io.spring.dependency-management' version '1.0.9.RELEASE'
 17 }
 18 description="flight-sample"
 19 
 20 ext {
 21 
 22 
 23     //================= datasource ================
 24     mysqlConnectorJavaVersion = "8.0.19"
 25     druidStarterVersion = "1.1.18"
 26     druidVersion = "1.0.31"
 27 
 28     mybatisPlusStarterVersion = "3.3.1"
 29 
 30     //=================json=======================
 31     fastjsonVersion = "1.2.62"
 32     gsonVersion = "2.8.6"
 33     jjwtVersion = "0.9.1"
 34 
 35     //=================cache=======================
 36     ehcacheVersion = "2.10.6"
 37 
 38     //=================httpclient=================
 39     httpclientVersion = "4.5.10"
 40     OkHttpVersion = "3.14.4"
 41 
 42     //================= tools====================
 43     GuavaVersion = "26.0-jre"
 44     validationApiVersion = "2.0.1.Final"
 45     protostuffVersion = "1.6.0"
 46     curatorVersion = "4.0.1"
 47     jacksonDataformatYamlVersion="2.9.8"
 48 
 49     //================= test ====================
 50     h2Version = "1.4.197"
 51 
 52 }
 53 
 54 configure(allprojects ) { abjects ->
 55     apply plugin: 'java'
 56     apply plugin: 'maven-publish'
 57     repositories {
 58 
 59         maven {
 60             url 'https://maven.aliyun.com/nexus/content/groups/public/'
 61         }
 62 
 63         maven {
 64             url = 'https://repo.spring.io/libs-milestone'
 65         }
 66 
 67         maven {
 68             url 'https://repo.spring.io/snapshot/'
 69         }
 70 
 71         maven {
 72             url = 'https://oss.sonatype.org/content/repositories/snapshots/'
 73         }
 74 
 75         mavenLocal()
 76 
 77     }
 78 }
 79 
 80 configure(subprojects){subjects ->
 81     apply plugin: 'java'
 82     apply plugin: 'maven'
 83     apply plugin: 'maven-publish'
 84     apply plugin: 'io.spring.dependency-management'
 85 
 86     group = 'com.td.flight'
 87     version = '0.0.1'
 88 
 89     repositories {
 90 
 91         maven {
 92             url 'https://maven.aliyun.com/nexus/content/groups/public/'
 93         }
 94 
 95         maven {
 96             url = 'https://repo.spring.io/libs-milestone'
 97         }
 98 
 99         maven {
100             url 'https://repo.spring.io/snapshot/'
101         }
102 
103         maven {
104             url = 'https://oss.sonatype.org/content/repositories/snapshots/'
105         }
106 
107         mavenLocal()
108     }
109 
110     dependencyManagement {
111         imports {
112             mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
113         }
114     }
115 
116     dependencies{
117         compile "org.springframework.boot:spring-boot-starter-aop"
118         compile "org.springframework.boot:spring-boot-autoconfigure"
119         compile "org.springframework.boot:spring-boot-configuration-processor"
120         compile "org.springframework.retry:spring-retry"
121         testImplementation 'org.junit.platform:junit-platform-commons:1.5.2'
122         testCompile "org.springframework.boot:spring-boot-starter-test"
123         testCompile "org.assertj:assertj-core:3.15.0"
124     }
125     test {
126         useJUnitPlatform()
127     }
128 
129 
130     compileJava {
131         sourceCompatibility = 1.8
132         targetCompatibility = 1.8
133         options.encoding = "UTF-8"
134     }
135 
136     task sourcesJar(type: Jar) {
137         from sourceSets.main.allJava
138         archiveClassifier = 'sources'
139     }
140 
141     task javadocJar(type: Jar) {
142         from javadoc
143         archiveClassifier = 'javadoc'
144     }
145 
146 }

2 搭建子模塊:boot-demo

 

type選擇gradle project

 

這里勾選web依賴(方便后面的測試),然后直接next->finish

 

這個時候,IDEA一直提示在importing gradle project,仿佛卡死在了這里

 

因為對於子項目xxx而言,IDEA為它自動生成了一個默認的build.gradle,這句mavenCentral()意思是從maven中心倉庫下載相關依賴,大家都知道去國外的網站下載這些資源肯定是慢的一批

 

這里我們手動停止build的動作,刪除其他無用配置(上面的父工程的build.gradle已經對所有的子項目做了配置,所以各個子工程里不需要再配了),只留下一句話

 

然后reimport all gradle projects

 

配置application.yaml

IDEA為我們默認生成的是application.properities文件,修改后綴為.yaml,然后添加port

 

配置controller:添加@RestController @RequestMapping注解,並寫一個方法

 

啟動測試

 

處理父子模塊依賴:

修改父工程的settings.gradle,使子模塊boot-demo屬於父模塊,多個子模塊可以使用下面的逗號隔開的書寫格式。寫完include后,IDEA應該會自動重新import, 如果沒有,則按上面的步驟執行reimport all gradle projects

 

如果gradle項目呈現出下圖所示的所屬結構,則證明子父模塊依賴弄好了。

 

PS: 每新建一個module,都會生成一個和父工程同級的item (如下圖所示),我們需要選中它,點擊減號清理掉它(不然會有一些不必要的麻煩)

 

3 搭建子模塊:mybatisplus-demo

參考:https://www.cnblogs.com/happy4java/p/11206801.html

對於Mybatisplus-demo模塊的yaml文件有詳細注釋,方便以后學習:https://www.cnblogs.com/lgg20/archive/2019/10/28/11752946.html

和第2步搭建的boot-demo模塊步驟基本一致,唯一的區別在於build.gradle文件中多引入了一些依賴(紅框中的兩個是必須的,其他的是我為了測試弄的)

 

build.gradle的腳本

 1 configurations {
 2     mybatisGenerator
 3 }
 4 dependencies {
 5     implementation 'org.springframework.boot:spring-boot-starter-web'
 6     compile "com.baomidou:mybatis-plus-boot-starter:${mybatisPlusStarterVersion}"
 7     implementation "mysql:mysql-connector-java:${mysqlConnectorJavaVersion}"
 8     //implementation 'org.projectlombok:lombok:1.18.2'
 9     implementation 'org.mybatis.generator:mybatis-generator-core:1.3.5'
10     //mybatisGenerator 'mysql:mysql-connector-java:${mysqlConnectorJavaVersion}'
11     //implementation 'tk.mybatis:mapper:3.3.9'
12     //implementation 'tk.mybatis:mapper-spring-boot-starter:2.0.0'
13     annotationProcessor 'org.projectlombok:lombok:1.18.2'
14     compileOnly 'org.projectlombok:lombok:1.18.2'
15 }

配置application.yaml

 1 spring:
 2   datasource:
 3     driver-class-name: com.mysql.cj.jdbc.Driver
 4     url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false
 5     username: root
 6     password: root
 7 mybatis-plus:
 8   mapper-locations: classpath:/mybatis/*Dao.xml
 9   #實體掃描,多個package用逗號或者分號分隔
10   type-aliases-package: com.example.entity
11   global-config:
12   #主鍵類型  0:"數據庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數字類型唯一ID)", 3:"全局唯一ID UUID";
13     id-type: 3
14     #字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
15     field-strategy: 2
16     #駝峰下划線轉換
17     db-column-underline: true
18     logic-delete-value: 1
19     logic-not-delete-value: 0
20   configuration:
21     map-underscore-to-camel-case: true
22     cache-enabled: false
23 server:
24   port: 8097

新建controller/mapper/entity/config

controller

 1 @RestController
 2 public class UserController {
 3 
 4     @Autowired
 5     private UserDao UserDao;
 6 
 7     @RequestMapping("/getUserInfoById")
 8     public User getUserInfoById(){
 9         //List<User> users = UserDao.selectAll();
10         User user = UserDao.selectById("1");
11         return user;
12     }
13     @RequestMapping("/getUserList")
14     public List<User> getUserList(){
15         List<User> users = UserDao.selectList(new QueryWrapper<>());
16         return users;
17     }
18     @RequestMapping("/hello")
19     public String hello(){
20         return "hello";
21     }
22     @RequestMapping("/insertUserInfo")
23     public String insertUserInfo(){
24         String result = "";
25         User user = new User();
26         user.setName("飛飛飛");
27         user.setEmail("121213@163.com");
28         user.setAge(21);
29         int count = UserDao.insert(user);
30         if(count > 0){
31             result = "插入成功!";
32         } else {
33             result = "失敗!";
34         }
35         return result;
36     }
37 }

mapper

1 @Mapper
2 public interface UserDao extends BaseMapper<User> {
3     //User findById(String id);
4 }

entity

1 @Data
2 @TableName("user")
3 public class User{
4     @TableId
5     private String id;
6     private String name;
7     private int age;
8     private String email;
9 }

config

 1 @Configuration
 2 @MapperScan("com.example.dao")//掃描文件
 3 public class MybatisPlusConfig {
 4 
 5     /*
 6      * 分頁插件,自動識別數據庫類型
 7      * 多租戶,請參考官網【插件擴展】
 8      */
 9     @Bean
10     public PaginationInterceptor paginationInterceptor() {
11         return new PaginationInterceptor();
12     }
13 }

項目結構

測試

查詢(根據id查詢,為了方便,id在代碼中寫死了)

 

 

 

DB中的數據

 

 

 

插入數據(為了方便,要插入的User對象直接在代碼中寫死了)

 

 

 

DB中的數據

 

 

 4 搭建子模塊:security-demo

build.gradle文件

1 dependencies {
2     compile project(":mybatisplus-demo")
3     implementation 'org.springframework.boot:spring-boot-starter-security'
4     implementation 'org.springframework.boot:spring-boot-starter-web'
5     annotationProcessor 'org.projectlombok:lombok:1.18.2'
6     compileOnly 'org.projectlombok:lombok:1.18.2'
7 }

測試用的類ref: https://www.cnblogs.com/telwanggs/p/10802851.html

這里說一下我對springSecurity工作原理的初步認識:

 

shiro架構初步解讀:

 

 

 

 

 

 解釋:user想和application交互之前,必須先問問security manager同不同意,security manager需要去咨詢一下realm,最終做出決定。

PS: 在搭建mybatisplus-demo模塊的過程中,踩了很多坑,在這里Mark一下

1:在build gradle項目的時候,一直提示cannot find implement()IDEA把問題定位到了build.gradle的文件中的這些位置,做法:在gradle中直接移除子模塊,再reimport (ref步驟2中的PS部分)

 

2:在所有的配置項,測試類寫好之后,開始測試的時候,web頁面一直提示:Whitelabel Error Page,百度了一下:一般出現這個問題的原因就是目錄結構不正確,導致主應用程序類(Main application class)掃描不到controller類。默認情況下主應用程序類(Main application class)只會掃描同一包下的Class。對照了一下自己的,我是把啟動類放到了config包下,所以導致掃描不到其他包,做法:把啟動類拖出來,和com.example同級。

 

3web頁面訪問查數據的url (getUserInfoById),在web頁面死活不返回數據,只有一個大大的 {}, 里面什么都沒有;同時類里面的user.setXXXX() 等方法報一系列亂碼,當時我就懵逼了,反思了一下:我userentity用的lombok,然后百度了一下lombokgradle依賴引入,原來是我的引用方式不對。在gradle4.7版本以后甚至現在gradle5.0了里面這種方式會產生警告,在gradle5.0里面會直接報編譯錯誤。正確使用可以采用如下方式:

1 annotationProcessor 'org.projectlombok:lombok:1.18.2'
2 compileOnly 'org.projectlombok:lombok:1.18.2'

注釋掉的是我寫的錯的。

 

Lombok的使用:主要是entity中少些了一些setter getter等方法。

 

4:本來用的是mybatisplus框架,因為在搭模塊的時候參考了網上的一些資料,竟然陰差陽錯的又引入了另外一個mybatis框架:tk.mybatis,然后就遇到了下面的問題:java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.<init>(),使用selectByPrimaryKey無法根據主鍵查找獲取結果,解決方法:在寫實體類時,引入@Id注解時,導入正確的包:import javax.persistence.Id

而我導成了:org.springframework.data.annotation.Id (當然最后注釋掉了tk.mybatis相關的依賴,不然會沖突,這里只是mark一下遇到這個問題的解決方法)

同時應該只保留一種Mybatis相關的框架依賴,我原來是兩個共存(不知道是抽什么風加進去的。。。)

 

 

 

PS: 其他細節,后續再補上,今天先寫到這里 --- 20200408-23:03

補充(2020.4.22)

1 刪除項目中的無用文件:

 

刪除所有子模塊中的gradlew文件
刪除所有子模塊中的gradlew.bat文件
刪除所有子模塊中的gradle文件夾
刪除所有子模塊中的.gitignore文件,在項目最外層配置.gitignore文件,做為整個項目的git提交忽略配置

 

 github: 暫時未公開

PS: 第一次寫博客,難免有不妥的地方,希望理解。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM