點擊上方「成猿之路」,選擇「置頂公衆號」
html
技術文章第一時間送達!java
做者:calebmanmysql
https://www.jianshu.com/p/95946d6b0c7dnginx
本文簡介
爲何使用SpringBootgit
搭建怎樣一個環境github
開發環境web
導入快速啓動項目spring
集成前準備sql
集成Mybatis數據庫
集成Swagger2
多環境配置
多環境下的日誌配置
經常使用配置
爲何使用SpringBoot
SpringBoot相對於傳統的SSM框架的優勢是提供了默認的樣板化配置,簡化了Spring應用的初始搭建過程,若是你不想被衆多的xml配置文件困擾,能夠考慮使用SpringBoot替代
搭建怎樣一個環境
本文將基於Spring官方提供的快速啓動項目模板集成Mybatis、Swagger2框架,並講解mybatis generator一鍵生成代碼插件、logback、一鍵生成文檔以及多環境的配置方法,最後再介紹一下自定義配置的註解獲取、全局異常處理等常常用到的東西。
開發環境
本人使用IDEA做爲開發工具,IDEA下載時默認集成了SpringBoot的快速啓動項目能夠直接建立,若是使用Eclipse的同窗能夠考慮安裝SpringBoot插件或者直接從這裏配置並下載SpringBoot快速啓動項目,須要注意的是本次環境搭建選擇的是SpringBoot2.0的快速啓動框架,SpringBoot2.0要求jdk版本必需要在1.8及以上。
https://start.spring.io/
導入快速啓動項目
不論是由IDEA導入仍是現實下載模板工程都須要初始化快速啓動工程的配置,若是使用IDEA,在新建項目時選擇Spring Initializr,主要配置以下圖
IDEA新建SpringBoot項目-填寫項目/包名
IDEA新建SpringBoot項目-選擇依賴包
點擊next以後finish以後IDEA顯示正在下載模板工程,下載完成後會根據pom.xml下載包依賴,依賴下載完畢後模板項目就算建立成功了,若是是直接從官方網站配置下載快速啓動項目可參考下圖配置
直接下載SpringBoot快速啓動項目-項目配置
從Search for dependencies 框中輸入並選擇Web、Mysql、Mybatis加入依賴,點擊Generate Project下載快速啓動項目,而後在IDE中選擇導入Maven項目,項目導入完成後可見其目錄結構以下圖
快速啓動項目-項目結構
須要關注紅色方框圈起來的部分,由上往下第一個java類是用來啓動項目的入口函數,第二個properties後綴的文件是項目的配置文件,第三個是項目的依賴包以及執行插件的配置
集成前準備
修改.properties爲.yml
yml相對於properties更加精簡併且不少官方給出的Demo都是yml的配置形式,在這裏咱們採用yml的形式代替properties,相對於properties形式主要有如下兩點不一樣
對於鍵的描述由原有的 "." 分割變成了樹的形狀
對於全部的鍵的後面一個要跟一個空格,否則啓動項目會報配置解析錯誤
# properties式語法描述
spring.datasource.name = mysql
spring.datasource.url = jdbc:mysql://localhost:3306/db?characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 123
# yml式語法描述
spring:
datasource:
name: mysql
url: jdbc:mysql://localhost:3306/db?characterEncoding=utf-8
username: root
password: 123
配置所需依賴
快速啓動項目建立成功後咱們觀察其pom.xml文件中的依賴以下圖,包含了咱們選擇的Web、Mybatis以及Mysql
<!-- spring web mvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
可是咱們使用ORM框架通常還會配合數據庫鏈接池以及分頁插件來使用,在這裏我選擇了阿里的druid以及pagehelper這個分頁插件,再加上咱們還須要整合swagger2文檔自動化構建框架,因此增長了如下四個依賴項
<!-- 分頁插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<!-- alibaba的druid數據庫鏈接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- alibaba的json格式化對象 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<!-- 自動生成API文檔 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>
集成Mybatis
Mybatis的配置主要包括了druid數據庫鏈接池、pagehelper分頁插件、mybatis-generator代碼逆向生成插件以及mapper、pojo掃描配置
配置druid數據庫鏈接池
添加如下配置至application.yml文件中
spring:
datasource:
# 若是存在多個數據源,監控的時候能夠經過名字來區分開來
name: mysql
# 鏈接數據庫的url
url: jdbc:mysql://localhost:3306/db?characterEncoding=utf-8
# 鏈接數據庫的帳號
username: root
# 鏈接數據庫的密碼
password: 123
# 使用druid數據源
type: com.alibaba.druid.pool.DruidDataSource
# 擴展插件
# 監控統計用的filter:stat 日誌用的filter:log4j 防護sql注入的filter:wall
filters: stat
# 最大鏈接池數量
maxActive: 20
# 初始化時創建物理鏈接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時
initialSize: 1
# 獲取鏈接時最大等待時間,單位毫秒
maxWait: 60000
# 最小鏈接池數量
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
# 鏈接保持空閒而不被驅逐的最長時間
minEvictableIdleTimeMillis: 300000
# 用來檢測鏈接是否有效的sql,要求是一個查詢語句
# 若是validationQuery爲null,testOnBorrow、testOnReturn、testWhileIdle都不會其做用
validationQuery: select count(1) from 'table'
# 申請鏈接的時候檢測,若是空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測鏈接是否有效
testWhileIdle: true
# 申請鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能
testOnBorrow: false
# 歸還鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能
testOnReturn: false
# 是否緩存preparedStatement,即PSCache
poolPreparedStatements: false
# 要啓用PSCache,必須配置大於0,當大於0時,poolPreparedStatements自動觸發修改成true
maxOpenPreparedStatements: -1
配置pagehelper分頁插件
# pagehelper分頁插件
pagehelper:
# 數據庫的方言
helperDialect: mysql
# 啓用合理化,若是pageNum < 1會查詢第一頁,若是pageNum > pages會查詢最後一頁
reasonable: true
代碼逆向生成插件mybatis-generator的配置及運行
mybatis-generator插件的使用主要分爲如下三步
1.pom.xml中添加mybatis-generator插件
<build>
<plugins>
<!-- 將Spring Boot應用打包爲可執行的jar或war文件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- mybatis generator 自動生成代碼插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<!-- 掃描resources/generator目錄下的generatorConfig.xml配置 -->
<configurationFile>
${basedir}/src/main/resources/generator/generatorConfig.xml
</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
2.建立逆向代碼生成配置文件generatorConfig.xml
參照pom.xml插件配置中的掃描位置,在resources目錄下建立generator文件夾,在新建的文件夾中建立generatorConfig.xml配置文件,文件的詳細配置信息以下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 運行方式:mvaen運行命令 mybatis-generator:generate -e -->
<!-- 數據庫驅動:選擇你的本地硬盤上面的數據庫驅動包-->
<properties resource="generator/generator.properties"/>
<classPathEntry location="${classPathEntry}"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<!--數據庫連接URL,用戶名、密碼 -->
<jdbcConnection
driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/${db}?characterEncoding=utf-8"
userId="${userId}"
password="${password}">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<javaModelGenerator targetPackage="${pojoTargetPackage}" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成映射文件的包名和位置-->
<sqlMapGenerator targetPackage="${mapperTargetPackage}" targetProject="src/main/resources">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!-- 生成DAO的包名和位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="${daoTargetPackage}" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 要生成的表 tableName是數據庫中的表名或視圖名 schema是數據庫名稱-->
<table tableName="%" schema="${db}"/>
</context>
</generatorConfiguration>
爲了將generatorConfig.xml配置模板化,在這裏將變更性較大的配置項單獨提取出來做爲一個generatorConfig.xml的配置文件,而後經過properties標籤讀取此文件的配置,這樣作的好處是當須要多處複用此xml時只須要關注少許的配置項。
在generatorConfig.xml同級建立generator.properties文件,現只須要配置generator.properties文件便可,配置內容以下
# 請手動配置如下選項
# 數據庫驅動:選擇你的本地硬盤上面的數據庫驅動包
classPathEntry = D:/CJH/maven-repository/mysql/mysql-connector-java/5.1.30/mysql-connector-java-5.1.30.jar
# 數據庫名稱、用戶名、密碼
db = db
userId = root
password = 123
# 生成pojo的包名位置 在src/main/java目錄下
pojoTargetPackage = com.spring.demo.springbootexample.mybatis.po
# 生成DAO的包名位置 在src/main/java目錄下
daoTargetPackage = com.spring.demo.springbootexample.mybatis.mapper
# 生成Mapper的包名位置 位於src/main/resources目錄下
mapperTargetPackage = mapper
3.運行mybatis-generator插件生成Dao、Model、Mapping
# 打開命令行cd到項目pom.xml同級目錄運行如下命令
mvn mybatis-generator:generate -e
mybatis掃描包配置
至此已經生成了指定數據庫對應的實體、映射類,可是還不能直接使用,須要配置mybatis掃描地址後才能正常調用
1.在application.yml配置mapper.xml以及pojo的包地址
mybatis:
# mapper.xml包地址
mapper-locations: classpath:mapper/*.xml
# pojo生成包地址
type-aliases-package: com.spring.demo.springbootexample.mybatis.po
2.在SpringBootExampleApplication.java中開啓Mapper掃描註解
@SpringBootApplication
@MapperScan("com.spring.demo.springbootexample.mybatis.mapper")
public class SpringBootExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootExampleApplication.class, args);
}
}
測試mapper的有效性
@Controller
public class TestController {
//替換成本身生成的mapper
@Autowired
UserMapper userMapper;
@RequestMapping("/test")
@ResponseBody
public Object test(){
//查詢該表的全部數據
return userMapper.selectByExample(null);
}
}
啓動SpringBootExampleApplication.java的main函數,若是沒有在application.yml特地配置server.port那麼springboot會採用默認的8080端口運行,運行成功將打印以下日誌
Tomcat started on port(s): 8080 (http) with context path ''
在瀏覽器輸入地址若是返回表格的中的全部數據表明mybatis集成成功
http://localhost:8080/test
集成Swagger2
Swagger2是一個文檔快速構建工具,可以經過註解自動生成一個Restful風格json形式的接口文檔,並能夠經過如swagger-ui等工具生成html網頁形式的接口文檔,swagger2的集成比較簡單,使用須要稍微熟悉一下,集成、註解與使用分以下四步
1.創建SwaggerConfig文件
@Configuration
public class SwaggerConfig {
// 接口版本號
private final String version = "1.0";
// 接口大標題
private final String title = "SpringBoot示例工程";
// 具體的描述
private final String description = "API文檔自動生成示例";
// 服務說明url
private final String termsOfServiceUrl = "http://www.kingeid.com";
// licence
private final String license = "MIT";
// licnce url
private final String licenseUrl = "https://mit-license.org/";
// 接口做者聯繫方式
private final Contact contact = new Contact("calebman", "https://github.com/calebman", "chenjianhui0428@gmail.com");
@Bean
public Docket buildDocket() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(buildApiInf())
.select().build();
}
private ApiInfo buildApiInf() {
return new ApiInfoBuilder().title(title).termsOfServiceUrl(termsOfServiceUrl).description(description)
.version(version).license(license).licenseUrl(licenseUrl).contact(contact).build();
}
}
2.在SpringBootExampleApplication.java中啓用Swagger2註解
在@SpringBootApplication註解下面加上@EnableSwagger2註解
3.經常使用註解示例
//Contorller中的註解示例
@Controller
@RequestMapping("/v1/product")
// 表示標識這個類是swagger的資源
@Api(value = "DocController", tags = {"restful api示例"})
public class DocController extends BaseController {
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
@ResponseBody
//表示一個http請求的操做
@ApiOperation(value = "修改指定產品", httpMethod = "PUT", produces = "application/json")
//@ApiImplicitParams用於方法,包含多個@ApiImplicitParam表示單獨的請求參數
@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "產品ID", required = true, paramType = "path")})
public WebResult update(@PathVariable("id") Integer id, @ModelAttribute Product product) {
logger.debug("修改指定產品接收產品id與產品信息=>%d,{}", id, product);
if (id == null || "".equals(id)) {
logger.debug("產品id不能爲空");
return WebResult.error(ERRORDetail.RC_0101001);
}
return WebResult.success();
}
}
//Model中的註解示例
//表示對類進行說明,用於參數用實體類接收
@ApiModel(value = "產品信息")
public class Product {
//表示對model屬性的說明或者數據操做更改
@ApiModelProperty(required = true, name = "name", value = "產品名稱", dataType = "query")
private String name;
@ApiModelProperty(name = "type", value = "產品類型", dataType = "query")
private String type;
}
4.生成json形式的文檔
集成成功後啓動項目控制檯會打印級別爲INFO的日誌,截取部分以下,代表可經過訪問應用的v2/api-docs接口獲得文檔api的json格式數據,可在瀏覽器輸入指定地址驗證集成是否成功
Mapped "{[/v2/api-docs],methods=[GET],produces=[application/json || application/hal+json]}"
http://localhost:8080/v2/api-docs
多環境配置
應用研發過程當中多環境是不可避免的,假設咱們如今有開發、演示、生產三個不一樣的環境其配置也不一樣,若是每次都在打包環節來進行配置不免出錯,SpringBoot支持經過命令啓動不一樣的環境,可是配置文件須要知足application-{profile}.properties
的格式,profile表明對應環境的標識,加載時可經過不一樣命令加載不一樣環境。
application-dev.properties:開發環境
application-test.properties:演示環境
application-prod.properties:生產環境
# 運行演示環境命令
java -jar spring-boot-example-0.0.1-SNAPSHOT --spring.profiles.active=test
基於如今的項目實現多環境咱們須要在application.yml同級目錄新建application-dev.yml、application-test.yml、application-prod.yml三個不一樣環境的配置文件,將不變的公有配置如druid的大部分、pagehelper分頁插件以及mybatis包掃描配置放置於application.yml中,並在application.yml中配置默認採用開發環境,那麼若是不帶--spring.profiles.active啓動應用就默認爲開發環境啓動,變更較大的配置如數據庫的帳號密碼分別寫入不一樣環境的配置文件中
spring:
profiles:
# 默認使用開發環境
active: dev
配置到這裏咱們的項目目錄結構以下圖所示
至此咱們分別完成了Mybatis、Swagger2以及多環境的集成,接下來咱們配置多環境下的logger。對於logger咱們老是但願在項目研發過程當中越多越好,可以給予足夠的信息定位bug,項目處於演示或者上線狀態時爲了避免讓日誌打印影響程序性能咱們只須要警告或者錯誤的日誌,而且須要寫入文件,那麼接下來就基於logback實現多環境下的日誌配置
多環境下的日誌配置
建立logback-spring.xml在application.yml的同級目錄,springboot推薦使用logback-spring.xml而不是logback.xml文件,logback-spring.xml的配置內容以下所示
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!--
簡要描述
日誌格式 => %d{HH:mm:ss.SSS}(時間) [%-5level](日誌級別) %logger{36}(logger名字最長36個字符,不然按照句點分割) - %msg%n(具體日誌信息而且換行)
開發環境 => ${basepackage}包下控制檯打印DEBUG級別及以上、其餘包控制檯打印INFO級別及以上
演示(測試)環境 => ${basepackage}包下控制檯打印INFO級別及以上、其餘包控制檯以及文件打印WARN級別及以上
生產環境 => 控制檯以及文件打印ERROR級別及以上
日誌文件生成規則以下:
文件生成目錄 => ${logdir}
當日的log文件名稱 => ${appname}.log
其餘時候的log文件名稱 => ${appname}.%d{yyyy-MM-dd}.log
日誌文件最大 => ${maxsize}
最多保留 => ${maxdays}天
-->
<!--自定義參數 -->
<!--用來指定日誌文件的上限大小,那麼到了這個值,就會刪除舊的日誌-->
<property name="maxsize" value="30MB" />
<!--只保留最近90天的日誌-->
<property name="maxdays" value="90" />
<!--application.yml 傳遞參數 -->
<!--log文件生成目錄-->
<springProperty scope="context" name="logdir" source="resources.logdir"/>
<!--應用名稱-->
<springProperty scope="context" name="appname" source="resources.appname"/>
<!--項目基礎包-->
<springProperty scope="context" name="basepackage" source="resources.basepackage"/>
<!--輸出到控制檯 ConsoleAppender-->
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<!--展現格式 layout-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{36} - %msg%n</pattern>
</pattern>
</layout>
</appender>
<!--輸出到文件 FileAppender-->
<appender name="fileLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--
日誌名稱,若是沒有File 屬性,那麼只會使用FileNamePattern的文件路徑規則
若是同時有<File>和<FileNamePattern>,那麼當天日誌是<File>,明天會自動把今天
的日誌更名爲今天的日期。即,<File> 的日誌都是當天的。
-->
<File>${logdir}/${appname}.log</File>
<!--滾動策略,按照時間滾動 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路徑,定義了日誌的切分方式——把每一天的日誌歸檔到一個文件中,以防止日誌填滿整個磁盤空間-->
<FileNamePattern>${logdir}/${appname}.%d{yyyy-MM-dd}.log</FileNamePattern>
<maxHistory>${maxdays}</maxHistory>
<totalSizeCap>${maxsize}</totalSizeCap>
</rollingPolicy>
<!--日誌輸出編碼格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 開發環境-->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="consoleLog"/>
</root>
<!--
additivity是子Logger 是否繼承 父Logger 的 輸出源(appender) 的標誌位
在這裏additivity配置爲false表明若是${basepackage}中有INFO級別日誌則子looger打印 root不打印
-->
<logger name="${basepackage}" level="DEBUG" additivity="false">
<appender-ref ref="consoleLog"/>
</logger>
</springProfile>
<!-- 演示(測試)環境-->
<springProfile name="test">
<root level="WARN">
<appender-ref ref="consoleLog"/>
<appender-ref ref="fileLog"/>
</root>
<logger name="${basepackage}" level="INFO" additivity="false">
<appender-ref ref="consoleLog"/>
<appender-ref ref="fileLog"/>
</logger>
</springProfile>
<!-- 生產環境 -->
<springProfile name="prod">
<root level="ERROR">
<appender-ref ref="consoleLog"/>
<appender-ref ref="fileLog"/>
</root>
</springProfile>
</configuration>
日誌配置中引用了application.yml的配置信息,主要有logdir、appname、basepackage三項,logdir是日誌文件的寫入地址,能夠傳入相對路徑,appname是應用名稱,引入這項是爲了經過日誌文件名稱區分是哪一個應該輸出的,basepackage是包過濾配置。
好比開發環境中須要打印debug級別以上的日誌,可是又想使除我寫的logger以外的DEBUG不打印,可過濾到本項目的包名才用DEBUG打印,此外包名使用INFO級別打印,在application.yml中新建這三項配置,也可在不一樣環境配置不一樣屬性
#應用配置
resources:
# log文件寫入地址
logdir: logs/
# 應用名稱
appname: spring-boot-example
# 日誌打印的基礎掃描包
basepackage: com.spring.demo.springbootexample
使用不一樣環境啓動測試logger配置是否生效,在開發環境下將打印DEBUG級別以上的四條logger記錄,在演示環境降低打印INFO級別以上的三條記錄並寫入文件,在生產環境下只打印ERROR級別以上的一條記錄並寫入文件
@RequestMapping("/logger")
@ResponseBody
public WebResult logger() {
logger.trace("日誌輸出 {}", "trace");
logger.debug("日誌輸出 {}", "debug");
logger.info("日誌輸出 {}", "info");
logger.warn("日誌輸出 {}", "warn");
logger.error("日誌輸出 {}", "error");
return "00";
}
經常使用配置
加載自定義配置
@Component
@PropertySource(value = {"classpath:application.yml"}, encoding = "utf-8")
public class Config {
@Value("${resources.midpHost}")
private String midpHost;
public String getMidpHost() {
return midpHost;
}
}
全局異常處理器
@ControllerAdvice
public class GlobalExceptionResolver {
Logger logger = LoggerFactory.getLogger(GlobalExceptionResolver.class);
@ExceptionHandler(value = Exception.class)
@ResponseBody
public WebResult exceptionHandle(HttpServletRequest req, Exception ex) {
ex.printStackTrace();
logger.error("未知異常", ex);
return WebResult.error(ERRORDetail.RC_0401001);
}
}
示例工程開源地址
https://github.com/calebman/spring-boot-example
推薦閱讀:
本文分享自微信公衆號 - 成猿之路(softwareload)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。