天天看點

補習系列(1)-springboot項目基礎搭建課

目錄

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 指向一個日志檔案,我們為該日志檔案設定了滾動的規則:

  1. 當大小超過50M時會生成新的日志;
  2. 每小時生成一個新的日志;

    指定了最多存在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篇"

補習系列(1)-springboot項目基礎搭建課

作者:

zale

出處:

http://www.cnblogs.com/littleatp/

, 如果喜歡我的文章,請

關注我的公衆号

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出

原文連結

 如有問題, 可留言咨詢.