該項目分爲幾個模塊:css
1,集成了mybatis。html
2,事務支持。前端
3,全局異常處理。java
4,靜態資源訪問。git
靜態資源:js, css, html, 圖片,音視頻等程序員
靜態資源路徑:是指系統能夠直接訪問的路徑,且路徑下的全部文件都可被用戶直接讀取。github
Spring Boot默認提供靜態資源目錄位置需置於classpath下,目錄名需符合以下規則:web
/staticredis
/publicspring
/resources
/META-INF/resources
在resources目錄下面創建static文件夾,在文件夾裏面任意放張圖片。
命名爲:enjoy.jpg
在地址欄上輸入localhost:8080/enjoy.jpg,能夠看到圖片
5,jsp集成
通常來講springboot不建議直接使用jsp頁面,但不排除有些公司的項目依然使用jsp作前端界面。
springboot內置的tomcat並無集成對jsp的支持,也沒有對EL表達式的支持,所以要使用jsp應該先把相關的依賴集成進來
在pom文件裏面新增
<!--JavaServer Pages Standard Tag Library,JSP標準標籤庫-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!--內置tocat對Jsp支持的依賴,用於編譯Jsp-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
因爲要springmvc解析jsp,要配置試圖解析器,在applicaiton.properties 裏面新增
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
在resources裏面新建WEB-INF文件夾,在裏面放一個index.jsp頁面
最後新建一個controller,注意這裏的註解是@Controller,千萬不能用@RestController
在瀏覽器上輸入:localhost:8080/jsp/hi,能夠看到JSP頁面。
6, 模板引擎
SpringBoot 推薦使用模板引擎來渲染html,若是你不是歷史遺留項目,必定不要使用JSP,經常使用的模板引擎不少,有freemark,thymeleaf等,其實都大同小異
其中springboot 強烈推薦的是用thymeleaf
pom文件種添加thymeleaf的支持,而且刪除JSP的支持
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--<!–JavaServer Pages Standard Tag Library,JSP標準標籤庫–>-->
<!--<dependency>-->
<!--<groupId>javax.servlet</groupId>-->
<!--<artifactId>jstl</artifactId>-->
<!--</dependency>-->
<!--<!–內置tocat對Jsp支持的依賴,用於編譯Jsp–>-->
<!--<dependency>-->
<!--<groupId>org.apache.tomcat.embed</groupId>-->
<!--<artifactId>tomcat-embed-jasper</artifactId>-->
<!--</dependency>-->
刪除application.properties文件裏面視圖解析器內容
#spring.mvc.view.prefix=/WEB-INF/jsp/
#spring.mvc.view.suffix=.jsp
Springboot默認的模板配置路徑爲:src/main/resources/templates
在resources目錄裏面新建一個templates目錄,在目錄裏面新建testThymeleaf.html文件
在瀏覽器上輸入:localhost:8080/tpl/testThymeleaf,能夠看到頁面。
7,集成swagger2構建api文檔
Swagger2 的做用
l隨項目自動生成強大RESTful API文檔,減小工做量
lAPI文檔與代碼整合在一塊兒,便於同步更新API說明
頁面測試功能來調試每一個RESTful API
訪問:http://localhost:8080/swagger-ui.html
8,集成日誌
java有許多的日誌組件,好比 log4j,log4j2,logback還有java自生提供的Java Util Logging,其實在springboot中對這些組件都提供了支持,log4j,log4j2和logback都提供相應的組件支持。
Logback
在springboot中默認使用的日誌工具是logback,不過在說起具體的日誌工具以前要提一個名詞,這個名詞就是slf4j(Simple Logging Facade For Java)
百度百科解釋https://baike.baidu.com/item/slf4j/6408868
slf4j不是具體的日誌解決方案,它有點相似於jdbc,使用了門面模式,是一個針對各種日誌的抽象實現,既然是抽象的日誌實現,在springboot中確定不須要額外導入。
注意:spring-boot-starter中就提供了對spring-boot-starter-logging的依賴
在spring-boot-starter-logging中能夠看到以及集成了slf4j與具體實現logback的默認支持
日誌級別:
修改controller 把日誌的輸出改爲logger.debug("這個一個hello日誌");這個時候重啓,再調用,發現後臺並不會有任何輸出,這緣由是日誌級別在做祟
默認狀況下,Spring Boot 配置的是INFO 日誌級別,也就是會輸出INFO級別以上的日誌(ERROR, WARN, INFO)。若是須要 Debug 級別的日誌。
在 src/main/resources/application.properties 中配置。debug=true 此外,配置 logging.level.* 來具體輸出哪些包的日誌級別。
例如
logging.level.root=INFO
logging.level.org.springframework.web=DEBUG
logging.level.cn.enjoy.controller=DEBUG
通常狀況下,springboot日誌只會輸出到控制檯,並不會寫入到日誌文件,可是,在一些正式環境的應用中,咱們須要經過在 application.properites 文件中配置 logging.file 文件名稱和 logging.path 文件路徑,將日誌輸出到日誌文件中。
logging.path = /var/tmp
logging.file = xxx.log
logging.level.root = info
注意:
若是隻配置 logging.path,在 /var/tmp文件夾生成一個日誌文件爲 spring.log。若是隻配置 logging.file,會在項目的當前路徑下生成一個 xxx.log 日誌文件
在spring-boot-dependencies POMs中搜索spring-boot-starter-log4j2
發現Spring boot父Pom中本身提供了這個依賴,因而咱們加入以下jar依賴:
修改pom.xml文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
注意: 因爲默認使用logback在擴展log4j2以前先要把logback移除
日誌使用跟上面logback同樣。
爲了防止在工做中常常在代碼中加入大量的日誌處理代碼,在實際項目開發中,通常使用AOP統一完成日誌處理工做。
9,springBoot熱加載部署
熱部署不會用在生產環境,但對於程序員開發的效率,仍是有必定幫助的,所謂的熱部署,就是在應用程序在不中止的狀況下,實現新的部署
spring-boot-devtools 是一個爲開發者服務的一個模塊,其中最重要的功能就是自動應用代碼更改到最新的App上面去。原理是在發現代碼有更改以後,從新啓動應用,可是速度比手動中止後再啓動還要更快,更快指的不是節省出來的手工操做的時間。
其深層原理是使用了兩個ClassLoader,一個Classloader加載那些不會改變的類(第三方Jar包),另外一個ClassLoader加載會更改的類,稱爲 restart ClassLoader
,這樣在有代碼更改的時候,原來的restart ClassLoader 被丟棄,從新建立一個restart ClassLoader,因爲須要加載的類相比較少,因此實現了較快的重啓時間
修改pom文件,增長
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
修改properties文件
若是使用的 Thymeleaf 模板,那麼請直接在application.properties中添加
spring.thymeleaf.cache=false
若是使用的 FreeMarker 模板,那麼請直接在application.properties中添加
spring.freemarker.cache=false
若是你是使用eclipse,請忽略,但若是你是使用IDEA,因爲idea 沒有保存修改的,也就是說在idea中並不會由於你ctrl+s 就從新編譯代碼。
那麼就須要額外的配置
在pom文件中,增長編譯插件,讓代碼有變更的時候也編譯
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 若是不設置fork,那麼不會restart,devtools熱部署不會起做用-->
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
一、手動:修改完代碼,按快捷鍵Ctrl+F9,手動構建項目,或者只修改單個類文件的話,按Ctrl+Shift+F9,從新編譯該類文件,便可觸發重啓服務。
二、自動
1)File -> Settings -> Compiler,勾選 Build Project automatically
2)按快捷鍵Ctrl+Shift+Alt+/,選擇1.Registry...
3)勾選 compiler.automake.allow.when.app.running 便可
這個時候修改JAVA文件或者模板文件都自動會生效
快速入門進行到這裏,其實已經差很少了,能應對絕大多數開發常見,接下來就是導包部署。
在pom文件中新增
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 若是不設置fork,那麼不會restart,devtools熱部署不會起做用-->
<fork>true</fork>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
使用mvn clean package 打包
java –jar 運行
若是並不但願使用內置的tomcat,但願部署到其餘tomcat服務器,那麼就須要使用war包部署了。
修改pom文件,打包方式改爲war
修改在pom文件,剔除內置tomcat的支持,不然會和外面的tomcat衝突
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--打包的時候能夠不用包進去,別的設施會提供。事實上該依賴理論上能夠參與編譯,測試,運行等週期。
至關於compile,可是打包階段作了exclude操做-->
<scope>provided</scope>
</dependency>
修改啓動類,使其繼承
@SpringBootApplication
@MapperScan("cn.enjoy.dao")
public class App extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(App.class);
}
}
使用mvn clean package 打包
把war包拷貝到tomcat webapps中
14,Actuator監控管理
Actuator是spring boot的一個附加功能,可幫助你在應用程序生產環境時監視和管理應用程序。可使用HTTP的各類請求來監管,審計,收集應用的運行狀況.特別對於微服務管理十分有意義
缺點:沒有可視化界面(Spring cloud 還會用到這功能,就能夠看到界面了)
修改pom文件,添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改application.properties文件,啓動監控端點
# 加載全部的端點/默認只加載了 info / health
management.endpoints.web.exposure.include=*
# 描述信息
info.blog-url=http://xiangxueketang.cn
info.author=enjoy
info.version=@project.version@
從新啓動,在地址欄輸入
http://localhost:8080/actuator/info
Actuator訪問路徑
經過actuator/+端點名就能夠獲取相應的信息。
路徑 |
做用 |
/actuator/beans |
顯示應用程序中全部Spring bean的完整列表。 |
/actuator/configprops |
顯示全部配置信息。 |
/actuator/env |
陳列全部的環境變量。 |
/actuator/mappings |
顯示全部@RequestMapping的url整理列表。 |
/actuator/health |
顯示應用程序運行情況信息 up表示成功 down失敗 |
/actuator/info |
查看自定義應用信息 |
15,多數據源與jta+atomikos分佈式事務
public static ConfigurableApplicationContext run(Class<?>[] primarySources,
String[] args) {
return new SpringApplication(primarySources).run(args);
}
其實SpringBoot啓動就着兩個步驟,先建立ConfigurableApplicationContext ,而後再調用Run方法。
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
//保存主類
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//判斷當前是什麼類型項目
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//從類路徑下找到META-INF/spring.factories配置的全部ApplicationContextInitializer
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//從類路徑下找到META-INF/spring.factories配置的全部ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
可見着一步很是簡單,只是把一些相關的類都加載了而已,並沒執行。
Run方法
真的重要是run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
//從類路徑下META‐INF/spring.factories,取得SpringApplicationRunListeners;
SpringApplicationRunListeners listeners = getRunListeners(args);
//回調全部的獲取SpringApplicationRunListener.starting()方法
listeners.starting();
try {
//封裝命令行參數
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//準備環境
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
configureIgnoreBeanInfo(environment);
//創回調SpringApplicationRunListener.environmentPrepared();
//表示環境準備完成
//打印Banner
Banner printedBanner = printBanner(environment);
//根據環境建立context
context = createApplicationContext();
//錯誤的異常報表
exceptionReporters = getSpringFactoriesInstances(
SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
//準備上下文環境;
//將environment保存到ioc中;
//applyInitializers()調用全部的ApplicationContextInitializer的initialize方法
//調用全部的SpringApplicationRunListener的contextPrepared();
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//SpringApplicationRunListener的contextLoaded
//刷新容器
//掃描,建立,加載全部組件;
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//全部的SpringApplicationRunListener回調started方法
listeners.started(context);
//獲取全部的ApplicationRunner和CommandLineRunner進行調用
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
//全部的SpringApplicationRunListener的running();
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}