目錄
springboot 最近火的不行,目前幾乎已經是 spring 家族最耀眼的項目了。抛開微服務、技術社群這些推廣因素不說,架構本身的确有非常多的優點。比如
- 更簡化的配置,摒除了許多繁雜的xml配置(事實證明,越簡單的東西越容易讓人記住);
- 内置Servlet容器,不再依賴外部環境
- 大量的starter子產品,随手拈來
- 支援熱部署
作為一名老程式員來說,仍然需要保持一個積極學習的态度。
哎,簡單點說就是少點傷感,認清現實。你曾經引以為傲的某某EE 技術已經被颠覆了,趕緊換車道 .....
廢話不多說,以下内容主要講的是怎麼利用springboot 這個腳手架搭建一個最精簡的項目。
其中幾個子產品會非常實用,這包括結構、配置、日志、部署..
springboot 項目仍然是使用maven 進行初始化及建構,下面是一個典型的結構:
目錄檔案 | 說明 |
---|---|
pom.xml | 依賴檔案 |
src/main/java | 代碼目錄 |
src/main/resources | 配置目錄,包含application.properties、log4j2.xml |
src/main/build | 定義建構檔案目錄 |
src/test/java | 測試代碼 |
src/test/resources | 測試配置 |
大緻看一下就行了,不了解maven的話,
點選這裡先學習入門,項目的建構工具是一定要先了解的。
可以通過eclipse 或idea 建立一個maven項目,再引入springboot依賴,pom檔案的定義參考如下:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.zales</groupId>
<artifactId>dmo-boot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>1.5.1.RELEASE</spring-boot.version>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- springboot application dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springweb -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
<exclusions>
<!-- exclude the default logging module -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- springboot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- used for livereload -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<version>${spring-boot.version}</version>
<optional>true</optional>
</dependency>
<!-- used for template -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${spring-boot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
springboot 官方的示例是讓你繼承一個spring-boot-parent,但這個很雞肋,通常的項目都會有自己的繼承結構。
是以我們間接利用spring-boot-dependencies将所有依賴引入,其他子產品的引入都是按需。
maven-compiler-plugin的定義用于将項目指定為
Java1.8的編譯級别。
其他途徑
你還可以利用spring的線上網站初始化一個springboot項目,
啟動代碼非常簡單,建立一個名為"DemoBoot**的類:
/**
* 入口類
*
*/
@SpringBootApplication
public class DemoBoot {
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(DemoBoot.class);
// 指定PID生成,預設輸出到application.pid
app.addListeners(new ApplicationPidFileWriter());
app.run(args);
}
}
再建立一個DemoController類:
@Controller
public class DemoController {
@RequestMapping("/")
@ResponseBody
String home() {
return "Hello World! ";
}
}
至此,我們已經完成了架構代碼!
熱部署
我們在定義項目依賴時添加了springboot-devtools,該子產品可以實作熱部署的功能,即在開發過程中可以不重新開機應用令代碼生效,非常友善
livereload 元件會定時掃描類路徑下的class,一旦發現變更即重新開機服務,預設1000毫秒檢測一次。
在定義依賴時指定optional 選項使得該子產品僅在開發時啟用。
livereload 在掃描會自動忽略以下範圍的變更:
META-INF/maven/**
META-INF/resources/**
resources/**,static/**
public/**
templates/**
**/*Test.class
**/*Tests.class
git.properties
META-INF/build-info.properties
在src/main/resources/下建立一個application.properties檔案,内容如下:
application.properties
server.address=0.0.0.0
server.port=8090
參數名稱 | 參數說明 |
---|---|
server.address | 監聽位址,不配置或0.0.0.0即不限制 |
server.port | 監聽端口 |
此時在IDE執行"DemoBoot",你應該可以看到一些描述程式啟動的日志資訊,通路本機的8090端口能看到"HelloWorld“輸出。
application.properties可包含大量的配置,你可以在
這裡找到全部的配置
接下來需要為應用準備一個日志配置用于定制,springboot 預設是使用logback的,但由于更加熟悉log4j的緣故,我們選用了log4j2.x
在src/main/resources/下建立一個log4j2.xml檔案,内容如下:
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="300">
<properties>
<property name="LOG_ROOT">log</property>
<property name="FILE_NAME">application</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}–[%t] %-5level -%l - %msg%n" />
</Console>
<RollingRandomAccessFile name="MainFile"
fileName="${LOG_ROOT}/${FILE_NAME}.log"
filePattern="${LOG_ROOT}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH}-%i.log">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}–[%t] %-5level -%l - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy interval="1" />
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
<DefaultRolloverStrategy max="20" />
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Logger name="org.zales" level="info" additivity="true">
<AppenderRef ref="MainFile" />
</Logger>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="MainFile" />
</Root>
</Loggers>
</Configuration>
這裡配置了兩個日志記錄方式,Console是控制台列印,RollingRandomAccessFile 指向一個日志檔案,我們為該日志檔案設定了滾動的規則:
- 當大小超過50M時會生成新的日志;
-
每小時生成一個新的日志;
指定了最多存在20個日志檔案。
之後,我們為主子產品(這裡是org.zales,你可以定義自己的包名)和ROOT都分别做了關聯和日志級别定義。
關于log4j2的用法,可以
參考這個文章
應用最終需要釋出到某個環境,那麼我們怎麼對springboot應用進行打包呢?
利用
spring-boot-maven-plugin可以将springboot項目達成jar包。
随後執行java -jar xxx.jar的方式即可以啟動應用。
這看起來好像很美好,但真實的項目釋出并非這麼簡單。
-
首先是配置,springboot的maven插件會将所有配置檔案都打進jar包内,而某些配置可能與環境相關。
比如應用端口,安全證書、或是日志配置等,這時我們希望在jar包外部存放這些檔案;
- 其次是執行腳本,在雲環境上釋出應用,通常需要提供啟停腳本,包括一些監控功能腳本,這些需要作為項目打包的一部分
- 最後,将應用程式釋出為tgz或zip格式的壓縮包會更加靈活,你可以添加更多的東西。
為實作靈活的打包方式,我們需要同時引用spring-boot-maven-plugin和maven-assembly-plugin兩個插件,如下:
<build>
<plugins>
<!-- build for springboot jar -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- build for application package -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>bundle</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${basedir}/src/main/build/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
plugin可以實作在maven的某個生命周期綁定一組動作,如上面的兩個插件都綁定到了package階段,執行順序由聲明的先後決定。
于是項目在執行mvn package這樣的指令時,會先執行springboot插件的repackage動作,将程式打包成jar檔案;随後通過assembly插件執行bundle任務,
再作最終的組裝。
/src/main/build/assembly.xml定義了程式包的結構,如下:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>bundle</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory> <!-- disable the creation of root's distribution dir in the archive -->
<fileSets>
<!-- config files -->
<fileSet>
<directory>${basedir}/src/main/build/config</directory>
<excludes></excludes>
<includes>
<include>application*.properties</include>
<include>log4j2.xml</include>
</includes>
<fileMode>0644</fileMode>
<outputDirectory>/</outputDirectory>
</fileSet>
<!-- scripts -->
<fileSet>
<directory>${basedir}/src/main/build/bin</directory>
<includes>
<include>*.sh</include>
</includes>
<fileMode>0755</fileMode>
<outputDirectory>/</outputDirectory>
</fileSet>
<!-- executable jar -->
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
<fileMode>0755</fileMode>
</fileSet>
</fileSets>
</assembly>
assembly檔案的定義比較簡單,目标程式包中除了jar檔案之外,還會包含幾個腳本和配置檔案。
-
啟動腳本
/src/main/build/bin/start.sh
nohup java -jar dmo-boot-0.0.1-SNAPSHOT.jar > console.log &
tail -n100 -f console.log
-
停止腳本
/src/main/build/bin/stop.sh
kill `cat application.pid`
rm application.pid
-
配置檔案
/src/main/build/application.properties
/src/main/build/log4j2.xml
最終執行"mvn package"打包,會輸出壓縮封包件,結構如下:
dmo-boot.0.0.1-SNAPSHOT.jar
application.properties
log4j2.xml
start.sh
stop.sh
本文将一個springboot項目從初始化、開發、配置、打包的整個流程進行了詳細介紹,希望讀者對該架構能産生整體性的了解。
由于篇幅有限,部分章節僅做了簡單說明。springboot是一個優秀的腳手架,借助于架構可以快速的完成各種特性的實作。
在随後的文章裡,将會跟大家一起繼續深入學習,歡迎随時關注"美碼師的補習系列-springboot篇"

作者:
zale出處:
http://www.cnblogs.com/littleatp/, 如果喜歡我的文章,請
關注我的公衆号本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出
原文連結如有問題, 可留言咨詢.