主頁 > 軟體設計 > Java:(一)自己動手實作一個好用的SpringBoot后端框架(專案搭建、組件依賴)

Java:(一)自己動手實作一個好用的SpringBoot后端框架(專案搭建、組件依賴)

2021-04-27 16:46:21 軟體設計

前言

這次準備分享一篇教程:如何自己動手實作一個好用的后端框架,我會盡量使用循序漸進的方式,從專案搭建開始,到集成各種組件,到最后架構完成,并集成基礎的用戶體系,一步步說明如何搭建一個屬于自己的后端框架,

基于現在大部分專案都是前后端分離的形式,因此本專案也是一個純后端的架構,基于循序漸進的原則,我打算先以 SpringBoot 單體專案的形式入手,先說明如何一步步集成各種組件,到最后形成一個完整的架構,后續有空的話,我會再以微服務的形式更新一篇教程,

限于我的技術水平也有限,抱著一起學習、共同進步的心態,在下文的分享程序中,如有發現問題,還請各位能及時幫忙指正,如有好的建議或者方案也請不吝賜教,希望大家能共同進步 😄

本教程的技術選型

用到的主要組件及說明(包括但不限于以下串列)

組件說明
SpringBoot專案基礎架構,集成了基本了框架能力
druid資料連接池,提供了資料庫連接池、監控等能力
MybatisPlus持久層組件
JWTJson Web Token,前后端分離時作為前端每次請求后臺介面的憑證
RSA非對稱加密演算法,JWT token加密需時要用到
ElasticSearchELK中的E,提供大資料量全文檢索能力
Redis高速快取組件
Swagger提供自動生成API介面檔案能力

還有一些組件如guava、kaptcha、lombok、minio等,在專案中我會盡量予以注釋說明
如果有需要用到Excel處理組件,可以選擇使用現成組件,如EasyExcel,或者參考下我的另一篇文章自己手動寫一個 《從原理入手,自己動手實作一個好用的Excel匯入匯出工具集》

本專案JDK版本使用是的1.8+

本教程適合哪些讀者

有一定的Java獨立開發能力,至少有使用SpringBoot搭建并運行過專案的經驗,其它的組件我感覺都是現學現賣,有不懂的也沒關系,先看明白怎么用,后面用熟了后自己再去摸索,

限于篇幅,我打算分幾篇文章來講解,下面正式開始

正式開始

一、搭建專案

這里照顧一下新手同學,先說明一下如何搭建一個Maven專案(如果這塊需要跳過,請直接電梯直達下一環節)

以IDEA為例,打開IDEA → \rightarrow File → \rightarrow New → \rightarrow Project… → \rightarrow Spring Initializer → \rightarrow Next
在這里插入圖片描述
填上專案的基礎資訊,繼續Next
在這里插入圖片描述
這一界面可以選擇勾選自己想到集成的組件,這里我們先不勾,后面我們自己在POM里去集成,這里直接Next
在這里插入圖片描述
填上專案的名稱(Project Name)及專案存盤位置(Project location)后直接點完成(Finish),完成后的Maven專案長這樣
在這里插入圖片描述
我們刪掉一些無用的檔案,只保留這些
在這里插入圖片描述
至此,我們搭建出了一個空的Maven專案,下面我們先把基礎的包結構建好,如下圖
在這里插入圖片描述
專案結構說明

包名說明
annotation存放各種自定義注解
config存放專案及組件配置
constants存放自定義常量或者列舉
controller存放各個模塊的控制層
dto資料傳輸物體
elasticsearch存放es相關的代碼(可選,需要用到es的話就建)
mapperdao層及其xml
model表映射物體
service服務層
utils存放各種工具類

二、準備組件依賴

我們打開pom.xml,來集成組件要用到依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.yinchd</groupId>
    <artifactId>web</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>WebBoot</name>
    <description>后端基礎架構</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <fastjson.version>1.2.75</fastjson.version>
        <swagger.version>3.0.0</swagger.version>
        <mybatis-plus.version>3.4.2</mybatis-plus.version>
        <mybatis-plus-generator.version>3.4.1</mybatis-plus-generator.version>
        <fastjson.version>1.2.60</fastjson.version>
        <log4j.version>1.2.17</log4j.version>
        <kaptcha.version>0.0.9</kaptcha.version>
        <druid.version>1.2.5</druid.version>
        <es.version>7.6.2</es.version>
        <velocity-engine-core.version>2.0</velocity-engine-core.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!-- 排除掉 內置 Tomcat -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--高性能web服務器-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>
        <!-- JUnit-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <!-- 配置引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- swagger3 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <!-- Mybatis-Plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
        <!-- MybatisPlus代碼生成器依賴 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatis-plus-generator.version}</version>
        </dependency>
        <!-- 模板引擎(Mybatis-Plus-Generator會用到) -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>${velocity-engine-core.version}</version>
        </dependency>

        <!-- spring boot redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- redis lettuce pool -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!-- guava-->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1-jre</version>
        </dependency>
        <!-- kaptcha 圖形驗證碼 -->
        <dependency>
            <groupId>com.github.axet</groupId>
            <artifactId>kaptcha</artifactId>
            <version>${kaptcha.version}</version>
        </dependency>
        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
        <!--commons-beanutils-->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>
        <!--bouncycastle (RSA加密要用到)-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.64</version>
            <scope>compile</scope>
        </dependency>
        <!--jwt-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
            <scope>compile</scope>
        </dependency>
        <!-- jasypt加密 -->
        <dependency>
            <groupId>com.github.ulisesbocchio</groupId>
            <artifactId>jasypt-spring-boot-starter</artifactId>
            <version>3.0.2</version>
        </dependency>

        <!-- minio檔案服務-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.1.0</version>
        </dependency>

        <!--elasticsearch-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>${es.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>${es.version}</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>${es.version}</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <!-- 因為我是把dao層生成的xml放在src/main/java目錄下,所以這里要讓生成的class檔案中包含這些xml檔案-->
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <!-- src/main/resources下的資源都包含進來 -->
                <includes>
                    <include>**/*.yml</include>
                    <include>**/*.xml</include>
                    <include>**/*.vm</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

</project>

三、Logback配置

因為spring-boot-starter-parent中已經有了日志組件相關的依賴,我們這里只須按我們自己的要求把日志配置一下即可使用

在resources目錄下建一個名為logback-spring.xml的檔案
在這里插入圖片描述
配置如下

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設定為WARN,則低于WARN的資訊都不會輸出 -->
<!-- scan:當此屬性設定為true時,組態檔如果發生改變,將會被重新加載,默認值為true -->
<!-- scanPeriod:設定監測組態檔是否有修改的時間間隔,如果沒有給出時間單位,默認單位是毫秒,當scan為true時,此屬性生效,默認的時間間隔為1分鐘, -->
<!-- debug:當此屬性設定為true時,將列印出logback內部日志資訊,實時查看logback運行狀態,默認值為false, -->
<configuration  scan="true" scanPeriod="60 seconds">
    <contextName>web-boot</contextName>
    <!-- name的值是變數的名稱,value的值時變數定義的值,通過定義的值會被插入到logger背景關系中,定義變數后,可以使“${}”來使用變數, -->
    <!-- 當天日志規則:日志根路徑/應用名稱/日志級別-應用埠.log  -->
    <!-- 歸檔日志規則:日志根路徑/應用名稱/archive/yyyy-MM/yyyy-MM-dd/日志級別/應用埠/xxx.log  -->
    <!-- ================== 您可能比較關注的基礎配置 ↓↓↓ ================= -->
    <!-- 應用名稱 -->
    <springProperty scope="context" name="spring.application.name" source="spring.application.name" defaultValue="unknown"/>
    <!-- 日志根路徑 -->
    <springProperty scope="context" name="log.root.path" source="logging.path" defaultValue="${user.home}/logs/"/>
    <!-- 日志完整路徑 -->
    <springProperty scope="context" name="log.path" source="log.root.path" defaultValue="${log.root.path}/${spring.application.name}"/>
    <!-- 應用埠 -->
    <springProperty scope="context" name="server.port" source="server.port" defaultValue="0000"/>
    <!-- ================== 您可能比較關注的基礎配置 ↑↑↑ ================= -->
    <!-- log name -->
    <!-- 控制臺彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!-- 檔案日志格式 -->
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>

    <!-- 彩色日志 -->
    <!-- 彩色日志依賴的渲染類 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />

    <!--輸出到控制臺-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是為開發使用,只配置最底級別,控制臺輸出的日志級別是大于或等于此級別的日志資訊-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <!--encoder 默認配置為PatternLayoutEncoder-->
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!--DEBUG日志輸出到檔案-->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志檔案的路徑及檔案名 -->
        <file>${log.path}/debug-${server.port}.log</file>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/archive/%d{yyyy-MM,aux}/%d{yyyy-MM-dd}/debug/${server.port}/debug.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志檔案保留天數-->
            <maxHistory>60</maxHistory>
            <!-- 該屬性在 1.1.6版本后 才開始支持-->
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志檔案只記錄DEBUG級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--日志檔案輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--INFO日志輸出到檔案-->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志檔案的路徑及檔案名 -->
        <file>${log.path}/info-${server.port}.log</file>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/archive/%d{yyyy-MM,aux}/%d{yyyy-MM-dd}/info/${server.port}/info.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志檔案保留天數-->
            <maxHistory>60</maxHistory>
            <!-- 該屬性在 1.1.6版本后 才開始支持-->
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志檔案只記錄DEBUG級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--日志檔案輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--WARN日志輸出到檔案-->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志檔案的路徑及檔案名 -->
        <file>${log.path}/warn-${server.port}.log</file>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/archive/%d{yyyy-MM,aux}/%d{yyyy-MM-dd}/warn/${server.port}/warn.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志檔案保留天數-->
            <maxHistory>60</maxHistory>
            <!-- 該屬性在 1.1.6版本后 才開始支持-->
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志檔案只記錄DEBUG級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--日志檔案輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--ERROR日志輸出到檔案-->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日志檔案的路徑及檔案名 -->
        <file>${log.path}/error-${server.port}.log</file>
        <!-- 日志記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/archive/%d{yyyy-MM,aux}/%d{yyyy-MM-dd}/error/${server.port}/error.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志檔案保留天數-->
            <maxHistory>60</maxHistory>
            <!-- 該屬性在 1.1.6版本后 才開始支持-->
            <totalSizeCap>20GB</totalSizeCap>
        </rollingPolicy>
        <!-- 此日志檔案只記錄DEBUG級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--日志檔案輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 異步輸出日志  -->
    <appender name="ASYNC_ROLLING_FILE" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 添加附加的appender,最多只能添加一個 -->
        <appender-ref ref="DEBUG_FILE"/>
        <!-- 不丟失日志.默認的,如果佇列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日志 -->
        <discardingThreshold >0</discardingThreshold>
        <!-- 更改默認的佇列的深度,該值會影響性能.默認值為256 -->
        <queueSize>256</queueSize>
        <includeCallerData>TRUE</includeCallerData>
    </appender>

    <!-- 輸出到控制臺和檔案,可定義更多的 Appender -->
    <root level="INFO">
        <appender-ref ref="ASYNC_ROLLING_FILE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
        <appender-ref ref="CONSOLE"/>
    </root>

    <!-- 測驗環境+開發環境. 多個使用逗號隔開.
        可以啟動服務的時候指定 profile (如不指定使用默認)
        如指定prod 的方式為:java -jar xxx.jar –spring.profiles.active=prod
    -->
    <springProfile name="test,dev,local">
        <!--additivity=true 傳遞給root,由root中的appender列印-->
        <logger name="com.yinchd" level="DEBUG" additivity="true"/>
        <logger name="com.ibatis" level="DEBUG" />
    </springProfile>
    <!-- 生產環境: 只列印INFO以上級別日志 -->
    <springProfile name="prod">
        <logger name="com.yinchd" level="INFO" additivity="false">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="INFO_FILE"/>
            <appender-ref ref="WARN_FILE"/>
            <appender-ref ref="ERROR_FILE"/>
        </logger>
    </springProfile>

</configuration>

上述主要配置了日志的輸出路徑、列印格式,列印級別等,其中日志默認存盤路徑我設定的是${user.home}/logs/,也即當前用戶的用戶目錄,這里也可以根據實際情況指定成其它路徑

關于用戶目錄:

Windows:比如當前登錄用戶是Administrator,則用戶目錄為“C:\Users\Administrator”
MacOS:Finder中為當前登錄用戶名的這個目錄
如不確定,可以執行Java代碼:System.out.println(System.getProperty("user.home"));查看自己的用戶目錄

三、application.yml配置

既然上述日志配置中,我們把日志分為了不同的級別,springProfile 為 prod的怎么處理日志,為dev、local的怎么處理日志,那我們也可以把不同的配置用不同的yml檔案隔離開來,本地開發時用本地的配置,測驗環境上測驗的配置,生產環境用生產的配置,互相隔離來,避免重復改動;

application.yml

spring:
  profiles:
    active: dev

上述配置代表當前激活的組態檔是dev,也即application-dev.xml,dev代表本地開發環境,這個命名是自己隨便定的,你改成local、xxx都可以,但是這里你用的什么名字,你就得有這么個組態檔,上面我叫dev,那么我就要建一個名叫application-dev.yml的組態檔

為了避免組態檔放得太凌亂,我們把測驗、生產或者其它的組態檔統統放到resources/config目錄下,比如下圖分別對應本地和生產的配置,如有更多環境的配置,也都放在這個目錄下
在這里插入圖片描述
因為激活的配置是application-dev.xml,那么我們就來配置application-dev.xml

application-dev.yml

# 專案運行的埠
server:
  port: 520

spring:
  # 專案名稱
  application:
    name: WebBoot
  servlet:
    multipart:
      enabled: true # 開啟檔案上傳
      max-file-size: 20MB # 檔案上傳限定大小
      max-request-size: 20MB # request請求限定大小
  # 資料源配置
  datasource:
    name: druidDataSource
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      # 這里填上你自己的資料庫地址及賬號密碼資訊(賬號密碼我使用了Druid的加密)
      url: jdbc:mysql://ip:3306/dbName?useUnicode=true&zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      username: root
      password: UhEfRcIkojy1LTHo3DjNyEXdGTEXo7+DPBc9MUL1s+SAvnhC1T3/m+HvAXZlP5fAMRWvN90r/iLdZCw2cUJSQw==
      # java -cp druid-1.2.5.jar com.alibaba.druid.filter.config.ConfigTools [your password] (注:如果不想加密,把下面publicKey和connection-properties兩項移除,密碼改回明文即可)
      key: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAK4WBLffpE4jIjSrBLp1Uh3YOm3OOBC1HjMqHhbHHGKr7QiZ1H06IXVQAg4yoVuv3lfG0i2k29WkgvqNh9hLPBcCAwEAAQ==
      connection-properties: "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;config.decrypt=true;config.decrypt.key=${spring.datasource.druid.key}"
      initial-size: 1
      max-active: 20
      filters: stat,wall,slf4j,config # slf4j: 對應logback
      max-wait: 60000
      min-idle: 1
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-open-prepared-statements: 20
      async-init: true
      web-stat-filter:
        enabled: true
        exclusions: "*.js, *.gif, *.jpg, *.png, *.css, *.ico, /v2/*, /swagger*, /druid/*"
      stat-view-servlet:
        enabled: true
        login-username: druid
        login-password: druid
        #allow: localhost # 只允許哪些地方可以訪問,一般填ip

  #redis 連接資訊
  redis:
    database: 0
    host: 192.168.1.10
    port: 6379
    password:
    lettuce:
      pool:
        max-active: 8
        max-wait: -1
        max-idle: 8
        min-idle: 0
    timeout: 5000

web:
  jwt:
    name: token
    secret: yinchd@Login(Auth}*^31)&
    # token過期時間(時間刻度:M月 d天 h小時 m分鐘 s秒)
    accessExpire: 2h
    # 重繪token過期時間
    refreshExpire: 1d
  # swagger控制開關
  swagger:
    enable: true
  # 檔案服務器地址
  file:
    minio: # minio檔案服務器
      server: localhost
      port: 9000
      accessKey: minioadmin
      secretKey: minioadmin
      secure: false
      # 檔案桶資訊
      bucketName: tank
    fdfs: # fastdfs檔案服務器
      server-url: http://192.168.1.10:1024/
      so-timeout: 5000
      connect-timeout: 5000
      thumb-image: #縮略圖生成引數
        width: 150
        height: 150
      tracker-list: #TrackerList引數,支持多個
        - 192.168.1.10:22122

# 日志配置
logging:
  config: classpath:logback-spring.xml
  level:
    io.swagger.models.parameters.AbstractSerializableParameter: error

# es配置
elasticsearch:
  schema: http
  address: 192.168.1.10:9200
  connectTimeout: 5000
  socketTimeout: 5000
  connectionRequestTimeout: 5000
  maxConnectNum: 100
  maxConnectPerRoute: 100

注意:上面資料源配置部分我使用了Druid的加密方式,Druid配置部分中的password和key要替換成你自己的加密資料才能用, 這里不知道怎么把明文密碼替換成密文的同學看一下我的這篇文章:《對yml組態檔中的資料庫連接資訊進行加密(Druid和Jasypt兩種方式)》 中Druid加密方式這一節,自己生成加密資料替換進去

本配置是假定你已經有Mysql、Redis等環境,上述配置中應將你自己的環境地址、埠等資訊替換成你自己的

如果你還沒有這些環境,建議先配置好,沒有配置過的同學可以參考下我之前做的配置筆記:
《Centos7安裝jdk、mysql、redis、nginx、fastdfs記錄》
《docker安裝Mysql》
或者度娘進行配置,一定要先把環境弄好

下面這段是檔案服務器的配置,如果你用不到檔案服務器,比如圖片、檔案上傳等,可以去掉這一段
在這里插入圖片描述

application-prod.yml

這個配置我們擬定為生產服務器上要用的配置,結構和application-dev.yml是一樣的,可能只是連接資訊或者賬號密碼的有些不同,這里暫且先不配置


本篇就暫且只講到配置部分,下一節我們來講組件具體怎么在代碼中集成和配置

下一節地址:《(二)自己動手實作一個好用的SpringBoot后端框架(集成代碼生成工具、Swagger)》

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/280670.html

標籤:其他

上一篇:分布式訊息中間件(2):Kafka系統學習—集群搭建與使用、副本機制和實時日志統計流程

下一篇:淺入淺出redis----II

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more