分類
發燒車訊

Maven系列第9篇:多環境構建支持,核心開發必備!

maven系列目標:從入門開始開始掌握一個高級開發所需要的maven技能。

這是maven系列第9篇。

整個maven系列的內容前後是有依賴的,如果之前沒有接觸過maven,建議從第一篇看起,本文尾部有maven完整系列的連接。

如果你作為公司核心開發,打算使用maven來搭建項目骨架,這篇文章的內容是你必須要掌握的。

平時我們在開發系統的時候,會有開發環境、測試環境、線上環境,每個環境中配置文件可能都是不一樣的,比如:數據庫的配置,靜態資源的配置等等,所以我們希望構建工具能夠適應不同環境的構建工作,能夠靈活處理,並且操作足夠簡單。Maven作為一款優秀的構建工具,這方面做的足夠好了,能夠很好的適應不同環境的構建工作,本文主要講解maven如何靈活的處理各種不同環境的構建工作,廢話不多說,上乾貨。

重點提示

本文中的所有案例均在上一篇的b2b項目上進行操作,上一篇還沒有看的可以移步過去看一下:

所有mvn命令均在b2b/pom.xml所在目錄執行。

Maven屬性

自定義屬性

maven屬性前面我們有用到過,可以自定義一些屬性進行重用,如下:

<properties>
    <spring.verion>5.2.1.RELEASE</spring.verion>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.verion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.verion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.verion}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.verion}</version>
    </dependency>
</dependencies>

可以看到上面依賴了4個spring相關的構建,他們的版本都是一樣的,在properties元素中自定義了一個spring.version屬性,值為spring的版本號,其他幾個地方使用${}直接進行引用,這種方式好處還是比較明顯的,升級spring版本的時候非常方便,只需要修改一個地方,方便維護。

上面這個是maven自定義屬性,需要先在properties中定義,然後才可以在其他地方使用${屬性元素名稱}進行引用。

maven的屬性主要分為2大類,第一類就是上面說的自定義屬性,另外一類是不需要自定義的,可以直接拿來使用的。

2類屬性在pom.xml中都是採用${屬性名稱}進行引用,maven運行的時候會將${}替換為屬性實際的值。

下面我們來看一下maven中不需要自定義的5類屬性。

內置屬性

${basedir}:表示項目根目錄,即包含pom.xml文件的目錄
${version}:表示項目的版本號

POM屬性

用戶可以使用該屬性引用pom.xml文件中對應元素的值,例如${project.artifactId}就可以取到project->artifactId元素的值,常用的有:

${pom.build.sourceDirectory}:項目的主源碼目錄,默認為src/main/java/
${project.build.testSourceDirectory}:項目的測試源碼目錄,默認為src/test/java/
${project.build.directory}:項目構建輸出目錄,默認為target/
${project.build.outputDirectory}:項目主代碼編譯輸出目錄,默認為target/classes
${project.build.testOutputDirectory}:項目測試代碼編譯輸出目錄,默認為target/test-classes
${project.groupId}:項目的groupId
${project.artifactId}:項目的artifactId
${project.version}:項目的version,與${version}等價
${project.build.finalName}:項目打包輸出文件的名稱,默認為${project.artifactId}-${project.version}

Settings屬性

這種屬性以settings.開頭來引用~/.m2/settings.xml中的內容,如:

${settings.localRepository}

指向用戶本地倉庫的地址。

java系統屬性

所有java系統屬性都可以使用maven屬性來進行引用,例如${user.home}指向了當前用戶目錄。

java系統屬性可以通過mvn help:system命令看到。

環境變量屬性

所有的環境變量都可以使用env.開頭的方式來進行引用,如:

${env.JAVA_HOME}

可以獲取環境變量JAVA_HOME的值。

用戶可以使用mvn help:system命令查看所有環境變量的值。

上面的maven屬性,我們在pom.xml中通過${屬性名稱}可以靈活的引用,對我們寫pom.xml文件幫助還是比較大的。

實操案例

將下面配置放在b2b-account-service/pom.xml中:

<properties>
    <!-- 項目的主源碼目錄,默認為src/main/java/ -->
    <a>${pom.build.sourceDirectory}</a>
    <!-- 項目的測試源碼目錄,默認為src/test/java/ -->
    <b>${project.build.testSourceDirectory}</b>
    <!-- 項目構建輸出目錄,默認為target/ -->
    <c>${project.build.directory}</c>
    <!-- 項目主代碼編譯輸出目錄,默認為target/classes -->
    <d>${project.build.outputDirectory}</d>
    <!-- 項目測試代碼編譯輸出目錄,默認為target/test-classes -->
    <e>${project.build.testOutputDirectory}</e>
    <!-- 項目的groupId -->
    <f>${project.groupId}</f>
    <!-- 項目的artifactId -->
    <g>${project.artifactId}</g>
    <!-- 項目的version,與${version}等價-->
    <h>${project.version}</h>
    <!-- 項目打包輸出文件的名稱,默認為${project.artifactId}-${project.version} -->
    <i>${project.build.finalName}</i>

    <!-- setting屬性 -->
    <!-- 獲取本地倉庫地址-->
    <a1>${settings.localRepository}</a1>

    <!-- 系統屬性 -->
    <!-- 用戶目錄 -->
    <a2>${user.home}</a2>

    <!-- 環境變量屬性,獲取環境變量JAVA_HOME的值 -->
    <a3>${env.JAVA_HOME}</a3>
</properties>

然後在b2b/pom.xml所在目錄執行下面命令:

D:\code\IdeaProjects\b2b>mvn help:effective-pom -pl :b2b-account-service > 1.xml

上面這個命令會將mvn ...執行的結果輸出到b2b/1.xml目錄,mvn這段命令有看不懂的朋友,可以去看看前面的文章。

b2b目錄中產生了一個1.xml,如下:

我們打開1.xml看一下,部分內容如下:

<properties>
  <a>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\main\java</a>
  <a1>${settings.localRepository}</a1>
  <a2>C:\Users\Think</a2>
  <a3>D:\installsoft\Java\jdk1.8.0_121</a3>
  <b>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\src\test\java</b>
  <b2>D:\code\IdeaProjects\b2b</b2>
  <c>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target</c>
  <d>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\classes</d>
  <e>D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\test-classes</e>
  <f>com.javacode2018</f>
  <g>b2b-account-service</g>
  <h>1.0-SNAPSHOT</h>
  <i>b2b-account-service-1.0-SNAPSHOT</i>
</properties>

大家去和上面的pom.xml中的對比一下,感受一下!

多套環境構建問題

b2b-account-service會操作數據庫,所以我們需要一個配置文件來放數據庫的配置信息,配置文件一般都放在src/main/resources中,在這個目錄中新建一個jdbc.properties文件,內容如下:

jdbc.url=jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

現在系統需要打包,我們運行下面命令

mvn clean package -pl :b2b-account-service

問題來了:

上面jdbc的配置的是開發庫的db信息,打包之後生成的jar中也是上面開發環境的配置,那麼上測試環境是不是我們需要修改上面的配置,最終上線的時候,上面的配置是不是又得重新修改一次,相當痛苦的。

我們能不能寫3套環境的jdbc配置,打包的時候去指定具體使用那套配置?

還是你們聰明,maven支持這麼做,pom.xml的project元素下面提供了一個profiles元素可以用來對多套環境進行配置。

在講profiles的使用之前,需要先了解資源文件打包的過程。

理解資源文件打包過程

我們將src/main/resouces/jdbc.properties複製一份到src/test/resources目錄,2個文件如下:

我們先運行一下下面命令:

mvn clean package -pl :b2b-account-service

輸出如下:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.572 s
[INFO] Finished at: 2019-11-21T17:13:20+08:00
[INFO] ------------------------------------------------------------------------

再去看一下項目的target目錄,如下圖:

下面我們來對這個過程做詳細分析:

從輸出中可以看到有下面幾行:

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource

從上面輸出中可以看出,使用了插件maven-resources-plugin的resources目標,將src/main/resouces目錄中的資源文件複製到了target/classess目錄,複製了一個文件,複製過程中使用是GBK編碼。

還有幾行輸出如下:

[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource

從上面輸出中可以看出,使用了插件maven-resources-plugin的testResources目標,將src/main/resouces目錄中的資源文件複製到了target/classess目錄,複製了一個文件,複製過程中使用是GBK編碼。

resources目錄中的文件一般放的都是配置文件,配置文件一般最好我們都不會寫死,所以此處有幾個問題:

  1. 這個插件複製資源文件如何設置編碼?
  2. 複製的過程中是否能夠對資源文件進行替換,比如在資源文件中使用一些佔位符,然後複製過程中對這些佔位符進行替換。

maven-resources-plugin這個插件還真好,他也想到了這個功能,幫我們提供了這樣的功能,下面我們來看看。

設置資源文件複製過程採用的編碼

這個之前有提到過,有好幾種方式,具體可以去前面的文章看一下。這裏只說一種:

<properties>
    <encoding>UTF-8</encoding>
</properties>

設置資源文件內容動態替換

資源文件中可以通過${maven屬性}來引用maven屬性中的值,打包的過程中這些會被替換掉,替換的過程默認是不開啟的,需要手動開啟配置。

修改src/main/resource/jdbc.properties內容如下:

jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}

修改src/test/resource/jdbc.properties內容如下:

jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}

b2b-account-service/pom.xml中加入下面內容:

<properties>
    <!-- 指定資源文件複製過程中採用的編碼方式 -->
    <encoding>UTF-8</encoding>
    <jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
    <jdbc.username>root</jdbc.username>
    <jdbc.password>root</jdbc.password>
</properties>

開啟動態替換配置,需要在pom.xml中加入下面配置:

<build>
    <resources>
        <resource>
            <!-- 指定資源文件的目錄 -->
            <directory>${project.basedir}/src/main/resources</directory>
            <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
            <filtering>true</filtering>
        </resource>
    </resources>
    <testResources>
        <testResource>
            <!-- 指定資源文件的目錄 -->
            <directory>${project.basedir}/src/test/resources</directory>
            <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
            <filtering>true</filtering>
        </testResource>
    </testResources>
</build>

注意上面開啟動態替換的元素是filtering

上面build元素中的resourcestestResources是用來控制構建過程中資源文件配置信息的,比資源文件位於哪個目錄,需要複製到那個目錄,是否開啟動態過濾等信息。

resources元素中可以包含多個resource,每個resource表示一個資源的配置信息,一般使用來控制主資源的複製的。

testResources元素和testResources類似,是用來控制測試資源複製的。

最終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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javacode2018</groupId>
    <artifactId>b2b-account-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- 指定資源文件複製過程中採用的編碼方式 -->
        <encoding>UTF-8</encoding>
        <jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
        <jdbc.username>root</jdbc.username>
        <jdbc.password>root</jdbc.password>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.javacode2018</groupId>
            <artifactId>b2b-account-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/main/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/test/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </testResource>
        </testResources>
    </build>

</project>

運行下面命令看效果:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.798 s
[INFO] Finished at: 2019-11-21T17:53:48+08:00
[INFO] ------------------------------------------------------------------------

4個文件截圖看一下效果,如下:

target中的2個資源文件內容被動態替換掉了。

上面會將資源文件中${}的內容使用maven屬性中的值進行替換,${}中包含的內容默認會被替換,那麼我們是否可以自定義${}這個格式,比如我希望被##包含內容進行替換,這個就涉及到替換中分隔符的指定了,需要設置插件的一些參數。

自定義替換的分隔符

自定義分隔符,需要我們配置maven-resources-plugin插件的參數,如下:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <!-- 是否使用默認的分隔符,默認分隔符是${*}和@ ,這個地方設置為false,表示不啟用默認分隔符配置-->
            <useDefaultDelimiters>false</useDefaultDelimiters>
            <!-- 自定義分隔符 -->
            <delimiters>
                <delimiter>$*$</delimiter>
                <delimiter>##</delimiter>
            </delimiters>
        </configuration>
    </plugin>
</plugins>

delimiters中可以配置多個delimiter,可以配置#*#,其中的*表示屬性名稱,那麼資源文件中的#屬性名#在複製的過程中會被替換掉,*前後都是#,表示前後分隔符都一樣,那麼可以簡寫為#,所以#*##寫法是一樣的,我們去看一下源碼,delimiters的默認值如下:

this.delimiters.add("${*}");
this.delimiters.add("@");

案例

我們將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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javacode2018</groupId>
    <artifactId>b2b-account-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- 指定資源文件複製過程中採用的編碼方式 -->
        <encoding>UTF-8</encoding>
        <jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
        <jdbc.username>root</jdbc.username>
        <jdbc.password>root</jdbc.password>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.javacode2018</groupId>
            <artifactId>b2b-account-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/main/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/test/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </testResource>
        </testResources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <!-- 是否使用默認的分隔符,默認分隔符是${*}和@ ,這個地方設置為false,表示不啟用默認分隔符配置-->
                    <useDefaultDelimiters>false</useDefaultDelimiters>
                    <!-- 自定義分隔符 -->
                    <delimiters>
                        <delimiter>$*$</delimiter>
                        <delimiter>##</delimiter>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

將兩個jdbc.properties修改成下面這樣:

jdbc.url=${jdbc.url}
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

再運行一下下面的命令:

mvn clean package -pl :b2b-account-service

看一下target/classes中的jdbc.properties文件,變成了下面這樣:

jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root

可以看到後面兩符合分隔符的要求,被替換了,第一個沒有被替換。

指定需要替換的資源文件

src/main/resources中新增一個const.properties文件,內容如下:

email=javacode2018@163.com
jdbc.url=${jdbc.url}
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

執行下面命令:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.667 s
[INFO] Finished at: 2019-11-21T18:26:01+08:00
[INFO] ------------------------------------------------------------------------

看一下target/classes中,如下圖:

target/classes/const.properties內容變成下面這樣了:

email=javacode2018@163.com
jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root

說明const.properteis也被替換了。2個資源文件都被複制到了target中,如果我們不想讓cont.properties被複制到target/classes目錄,我們怎麼做?我們需要在資源構建的過程中排除他,可以使用exclude元素信息進行排除操作。

修改pom.xml中resources元素配置如下:

<resources>
    <resource>
        <!-- 指定資源文件的目錄 -->
        <directory>${project.basedir}/src/main/resources</directory>
        <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
        <filtering>true</filtering>
        <includes>
            <include>**/jdbc.properties</include>
        </includes>
        <excludes>
            <exclude>**/const.properties</exclude>
        </excludes>
    </resource>
</resources>

上面使用includes列出需要被處理的,使用excludes排除需要被處理的資源文件列表,採用通配符的寫法,**匹配任意深度的文件路徑,*匹配任意個字符。

再執行下面命令:

mvn clean package -pl :b2b-account-service

再看一下target/classes中,如下:

const.properties被排除了,確實沒有被複制過來。

如果此時我想讓const.propertis只是被複制到target下面,但是不要去替換裏面的內容,該怎麼做呢?此時需要配置多個resouce元素了,如下案例。

多個resource元素的使用案例

修改pom.xml中resources,如下:

<resources>
    <resource>
        <!-- 指定資源文件的目錄 -->
        <directory>${project.basedir}/src/main/resources</directory>
        <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
        <filtering>true</filtering>
        <includes>
            <include>**/jdbc.properties</include>
        </includes>
    </resource>
    <resource>
        <directory>${project.basedir}/src/main/resources</directory>
        <includes>
            <include>**/const.properties</include>
        </includes>
    </resource>
</resources>

現在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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javacode2018</groupId>
    <artifactId>b2b-account-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- 指定資源文件複製過程中採用的編碼方式 -->
        <encoding>UTF-8</encoding>
        <jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
        <jdbc.username>root</jdbc.username>
        <jdbc.password>root</jdbc.password>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.javacode2018</groupId>
            <artifactId>b2b-account-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/main/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
                <includes>
                    <include>**/jdbc.properties</include>
                </includes>
            </resource>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <includes>
                    <include>**/const.properties</include>
                </includes>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/test/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </testResource>
        </testResources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <!-- 是否使用默認的分隔符,默認分隔符是${*}和@ ,這個地方設置為false,表示不啟用默認分隔符配置-->
                    <useDefaultDelimiters>false</useDefaultDelimiters>
                    <!-- 自定義分隔符 -->
                    <delimiters>
                        <delimiter>$*$</delimiter>
                        <delimiter>##</delimiter>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

執行命令看效果:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.116 s
[INFO] Finished at: 2019-11-21T18:38:59+08:00
[INFO] ------------------------------------------------------------------------

上面有如下輸出:

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource

插件處理了2個資源文件。

我們看一下target/classes目錄下兩個文件的內容。

jdbc.proerties:

jdbc.url=${jdbc.url}
jdbc.username=root
jdbc.password=root

const.properties:

email=javacode2018@163.com
jdbc.url=${jdbc.url}
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

2個資源都被複制到target/classes目錄了,只有jdbc.properties中的內容被替換了。

關於資源文件處理的,更詳細的過程可以去看這個插件的源碼,下面我們來說多環境處理的問題。

使用profiles處理多環境構建問題

maven支持讓我們配置多套環境,每套環境中可以指定自己的maven屬性,mvn命令對模塊進行構建的時候可以通過-P參數來指定具體使用哪個環境的配置,具體向下看。

profiles元素支持定義多套環境的配置信息,配置如下用法:

<profiles>
    <profile>測試環境配置信息</profile>
    <profile>開發環境配置信息</profile>
    <profile>線上環境配置信息</profile>
    <profile>環境n配置信息</profile>
</profiles>

profiles中包含多個profile元素,每個profile可以表示一套環境,profile示例如下:

<profile>
    <id>dev</id>
    <properties>
        <jdbc.url>dev jdbc url</jdbc.url>
        <jdbc.username>dev jdbc username</jdbc.username>
        <jdbc.password>dev jdbc password</jdbc.password>
    </properties>
</profile>

id:表示這套環境的標識信息,properties可以定義環境中使用到的屬性列表。

執行mvn命令編譯的時候可以帶上一個-P profileid來使用指定的環境進行構建。

指定環境進行構建

b2b-account-service/pom.xml加入下面配置:

<profiles>
    <!-- 開發環境使用的配置 -->
    <profile>
        <id>dev</id>
        <properties>
            <jdbc.url>dev jdbc url</jdbc.url>
            <jdbc.username>dev jdbc username</jdbc.username>
            <jdbc.password>dev jdbc password</jdbc.password>
        </properties>
    </profile>
    <!-- 測試環境使用的配置 -->
    <profile>
        <id>test</id>
        <properties>
            <jdbc.url>test jdbc url</jdbc.url>
            <jdbc.username>test jdbc username</jdbc.username>
            <jdbc.password>test jdbc password</jdbc.password>
        </properties>
    </profile>
    <!-- 線上環境使用的配置 -->
    <profile>
        <id>prod</id>
        <properties>
            <jdbc.url>test jdbc url</jdbc.url>
            <jdbc.username>test jdbc username</jdbc.username>
            <jdbc.password>test jdbc password</jdbc.password>
        </properties>
    </profile>
</profiles>

將pom.xml的project->properties中的下面幾個元素幹掉,這些和profile中的重複了,需要幹掉:

<jdbc.url>jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8</jdbc.url>
<jdbc.username>root</jdbc.username>
<jdbc.password>root</jdbc.password>

此時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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javacode2018</groupId>
    <artifactId>b2b-account-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <!-- 指定資源文件複製過程中採用的編碼方式 -->
        <encoding>UTF-8</encoding>
    </properties>

    <!-- 配置多套環境 -->
    <profiles>
        <!-- 開發環境使用的配置 -->
        <profile>
            <id>dev</id>
            <properties>
                <jdbc.url>dev jdbc url</jdbc.url>
                <jdbc.username>dev jdbc username</jdbc.username>
                <jdbc.password>dev jdbc password</jdbc.password>
            </properties>
        </profile>
        <!-- 測試環境使用的配置 -->
        <profile>
            <id>test</id>
            <properties>
                <jdbc.url>test jdbc url</jdbc.url>
                <jdbc.username>test jdbc username</jdbc.username>
                <jdbc.password>test jdbc password</jdbc.password>
            </properties>
        </profile>
        <!-- 線上環境使用的配置 -->
        <profile>
            <id>prod</id>
            <properties>
                <jdbc.url>prod jdbc url</jdbc.url>
                <jdbc.username>prod jdbc username</jdbc.username>
                <jdbc.password>prod jdbc password</jdbc.password>
            </properties>
        </profile>
    </profiles>

    <dependencies>
        <dependency>
            <groupId>com.javacode2018</groupId>
            <artifactId>b2b-account-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/main/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
                <includes>
                    <include>**/jdbc.properties</include>
                </includes>
            </resource>
            <resource>
                <directory>${project.basedir}/src/main/resources</directory>
                <includes>
                    <include>**/const.properties</include>
                </includes>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/test/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </testResource>
        </testResources>

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <!-- 是否使用默認的分隔符,默認分隔符是${*}和@ ,這個地方設置為false,表示不啟用默認分隔符配置-->
                    <useDefaultDelimiters>false</useDefaultDelimiters>
                    <!-- 自定義分隔符 -->
                    <delimiters>
                        <delimiter>$*$</delimiter>
                        <delimiter>##</delimiter>
                    </delimiters>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

修改src/main/resource/jdbc.properties內容如下:

jdbc.url=$jdbc.url$
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

運行下面的構建命令:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service -Pdev
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.361 s
[INFO] Finished at: 2019-11-21T18:51:16+08:00
[INFO] ------------------------------------------------------------------------

注意上面命令中多了一個-Pdev參數,-P後面跟的是pom.xml中profile的id,表示需要使用那套環境進行構建。此時我們使用的是dev環境,即開發環境。

看一下target/classes/jdbc.properties,內容變成了下面這樣:

jdbc.url=dev jdbc url
jdbc.username=dev jdbc username
jdbc.password=dev jdbc password

上面文件的內容和pom.xml中dev的profile中的properties對比一下,內容是不是一樣的,說明資源文件中內容被替換為了dev環境的配置,我們再來試試test環境,執行下面命令:

mvn clean package -pl :b2b-account-service -Ptest

看一下target/classes/jdbc.properties,內容變成了下面這樣:

jdbc.url=test jdbc url
jdbc.username=test jdbc username
jdbc.password=test jdbc password

看到了么,神奇的效果出現了,test環境起效了。

開啟默認環境配置

我們在執行下面命令:

mvn clean package -pl :b2b-account-service

看一下target/classes/jdbc.properties,內容變成了下面這樣:

jdbc.url=$jdbc.url$
jdbc.username=$jdbc.username$
jdbc.password=##jdbc.password##

內容沒有被替換,因為我們沒有通過-P來指定具體使用哪個環境進行構建,所以出現了這種現象。

但是我們可以指定一個默認開啟的配置,我們默認開啟dev的配置,修改dev的profile元素,在這個元素下面加上:

<activation>
    <activeByDefault>true</activeByDefault>
</activation>

activeByDefault表示默認開啟這個環境的配置,默認值是false,這個地方我們設置為true,表示開啟默認配置。

此時dev的配置如下:

<profile>
    <id>dev</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <jdbc.url>dev jdbc url</jdbc.url>
        <jdbc.username>dev jdbc username</jdbc.username>
        <jdbc.password>dev jdbc password</jdbc.password>
    </properties>
</profile>

執行下面命令:

mvn clean package -pl :b2b-account-service

看一下target/classes/jdbc.properties,內容變成了下面這樣:

jdbc.url=dev jdbc url
jdbc.username=dev jdbc username
jdbc.password=dev jdbc password

這次我們沒有指定環境,默認使用了dev環境。

通過maven屬性來控制環境的開啟

剛才上面說了通過-P profileId的方式來指定環境,現在我們想通過自定義的屬性值來控制使用哪個環境。

可以在profile元素中加入下面配置

<activation>
    <property>
        <name>屬性xx</name>
        <value>屬性xx的值</value>
    </property>
</activation>

那麼我們可以在mvn後面跟上下面的命令可以開啟匹配的環境:

mvn ... -D屬性xx=屬性xx的值

-D可以通過命令行指定一些屬性的值,這個前面有講過,-D後面的屬性會和activation->properties中的name、value進行匹配,匹配成功的環境都會被開啟。

將pom.xml中profiles元素修改成下面這樣:

<!-- 配置多套環境 -->
<profiles>
    <!-- 開發環境使用的配置 -->
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <property>
                <name>env</name>
                <value>env_dev</value>
            </property>
        </activation>
        <properties>
            <jdbc.url>dev jdbc url</jdbc.url>
            <jdbc.username>dev jdbc username</jdbc.username>
            <jdbc.password>dev jdbc password</jdbc.password>
        </properties>
    </profile>
    <!-- 測試環境使用的配置 -->
    <profile>
        <id>test</id>
        <activation>
            <property>
                <name>env</name>
                <value>env_test</value>
            </property>
        </activation>
        <properties>
            <jdbc.url>test jdbc url</jdbc.url>
            <jdbc.username>test jdbc username</jdbc.username>
            <jdbc.password>test jdbc password</jdbc.password>
        </properties>
    </profile>
    <!-- 線上環境使用的配置 -->
    <profile>
        <id>prod</id>
        <activation>
            <property>
                <name>env</name>
                <value>env_prod</value>
            </property>
        </activation>
        <properties>
            <jdbc.url>prod jdbc url</jdbc.url>
            <jdbc.username>prod jdbc username</jdbc.username>
            <jdbc.password>prod jdbc password</jdbc.password>
        </properties>
    </profile>
</profiles>

運行命令:

mvn clean package -pl :b2b-account-service -Denv=env_prod

target/classes/jdbc.properties內容如下:

jdbc.url=prod jdbc url
jdbc.username=prod jdbc username
jdbc.password=prod jdbc password

說明使用到了prod環境的配置。

啟動的時候指定多個環境

可以在-P參數後跟多個環境的id,多個之間用逗號隔開,當使用多套環境的時候,多套環境中的maven屬性會進行合併,如果多套環境中屬性有一樣的,後面的會覆蓋前面的。

運行下面命令看效果:

mvn clean package -pl :b2b-account-service -Pdev,test,prod

修改pom.xml中的profiles元素,如下:

<!-- 配置多套環境 -->
<profiles>
    <!-- 開發環境使用的配置 -->
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
            <property>
                <name>env</name>
                <value>env_dev</value>
            </property>
        </activation>
        <properties>
            <jdbc.url>dev jdbc url</jdbc.url>
        </properties>
    </profile>
    <!-- 測試環境使用的配置 -->
    <profile>
        <id>test</id>
        <activation>
            <property>
                <name>env</name>
                <value>env_test</value>
            </property>
        </activation>
        <properties>
            <jdbc.username>test jdbc username</jdbc.username>
        </properties>
    </profile>
    <!-- 線上環境使用的配置 -->
    <profile>
        <id>prod</id>
        <activation>
            <property>
                <name>env</name>
                <value>env_prod</value>
            </property>
        </activation>
        <properties>
            <jdbc.password>prod jdbc password</jdbc.password>
        </properties>
    </profile>
</profiles>

注意看一下上面3個環境中都只有一個自定義屬性了

下面我們同時使用3個環境,執行下面命令:

mvn clean package -pl :b2b-account-service -Pdev,test,prod

target中的jdbc.properties文件變成了這樣:

jdbc.url=dev jdbc url
jdbc.username=test jdbc username
jdbc.password=prod jdbc password

查看目前有哪些環境

命令:

mvn help:all-profiles

案例:

D:\code\IdeaProjects\b2b>mvn help:all-profiles -pl :b2b-account-service
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-help-plugin:3.2.0:all-profiles (default-cli) @ b2b-account-service ---
[INFO] Listing Profiles for Project: com.javacode2018:b2b-account-service:jar:1.0-SNAPSHOT
  Profile Id: dev (Active: true , Source: pom)
  Profile Id: prod (Active: false , Source: pom)
  Profile Id: test (Active: false , Source: pom)

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.527 s
[INFO] Finished at: 2019-11-21T19:16:34+08:00
[INFO] ------------------------------------------------------------------------

從輸出中可以看到有3個環境,他們的id,默認激活的是那個等信息。

查看目前激活的是哪些環境

命令:

mvn help:active-profiles

案例:

D:\code\IdeaProjects\b2b>mvn help:active-profiles -pl :b2b-account-service -Ptest,prod
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-help-plugin:3.2.0:active-profiles (default-cli) @ b2b-account-service ---
[INFO]
Active Profiles for Project 'com.javacode2018:b2b-account-service:jar:1.0-SNAPSHOT':

The following profiles are active:

 - test (source: com.javacode2018:b2b-account-service:1.0-SNAPSHOT)
 - prod (source: com.javacode2018:b2b-account-service:1.0-SNAPSHOT)



[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.387 s
[INFO] Finished at: 2019-11-21T19:25:56+08:00
[INFO] ------------------------------------------------------------------------

從輸出中可以看到啟用了2套環境,分別是testprod

新問題:配置太分散了

我們的系統中有2個模塊需要用到數據庫的配置,這兩個模塊是:

b2b-account-service
b2b-order-service

上面我們介紹了b2b-account-service不同環境的構建操作,是在pom.xml中進行配置的,b2b-order-service中數據的配置也可以這麼做,如果以後有更多的模塊都需要連接不同的數據庫,是不是每個模塊中都需要配置這樣的pom.xml,那時候數據庫的配置分散在幾十個pom.xml文件中,如果運維需要修改數據庫的配置的時候,需要去每個模塊中去修改pom.xml中的屬性,這種操作會讓人瘋掉的,我們可以怎麼做?

我們可以將數據庫所有的配置放在一個文件中,運維只用修改這一個文件就行了,然後執行構件操作,重新發布上線,就ok了。

maven支持我們這麼做,可以在profile中指定一個外部屬性文件xx.properties,文件內容是這種格式的:

key1=value1
key2=value2
keyn=value2

然後在profile元素中加入下面配置:

<build>
    <filters>
        <filter>xx.properties文件路徑(相對路徑或者完整路徑)</filter>
    </filters>
</build>

上面的filter元素可以指定多個,當有多個外部屬性配置文件的時候,可以指定多個來進行引用。

然後資源文件複製的時候就可以使用下面的方式引用外部資源文件的內容:

xxx=${key1}

案例

新建文件b2b/config/dev.properties,內容如下:

# b2b-account-service jdbc配置信息
b2b-account-service.jdbc.url=dev_account_jdbc_url
b2b-account-service.jdbc.username=dev_account_jdbc_username
b2b-account-service.jdbc.password=dev_account_jdbc_password

# b2b-order-service jdbc配置信息
b2b-order-service.jdbc.url=dev_order_jdbc_url
b2b-order-service.jdbc.username=dev_order_jdbc_username
b2b-order-service.jdbc.password=dev_order_jdbc_password

新建文件b2b/config/test.properties,內容如下:

# b2b-account-service jdbc配置信息
b2b-account-service.jdbc.url=test_account_jdbc_url
b2b-account-service.jdbc.username=test_account_jdbc_username
b2b-account-service.jdbc.password=test_account_jdbc_password

# b2b-order-service jdbc配置信息
b2b-order-service.jdbc.url=test_order_jdbc_url
b2b-order-service.jdbc.username=test_order_jdbc_username
b2b-order-service.jdbc.password=test_order_jdbc_password

新建文件b2b/config/prod.properties,內容如下:

# b2b-account-service jdbc配置信息
b2b-account-service.jdbc.url=prod_account_jdbc_url
b2b-account-service.jdbc.username=prod_account_jdbc_username
b2b-account-service.jdbc.password=prod_account_jdbc_password

# b2b-order-service jdbc配置信息
b2b-order-service.jdbc.url=prod_order_jdbc_url
b2b-order-service.jdbc.username=prod_order_jdbc_username
b2b-order-service.jdbc.password=prod_order_jdbc_password

b2b-account-service/src/main/resource/jdbc.properties文件內容:

jdbc.url=${b2b-account-service.jdbc.url}
jdbc.username=${b2b-account-service.jdbc.username}
jdbc.password=${b2b-account-service.jdbc.password}

看到了沒,這裏面${}中的屬性名稱取的是上面b2b/config目錄中資源文件中的屬性名稱。

b2b-order-service/src/main/resource/jdbc.properties文件內容:

jdbc.url=${b2b-order-service.jdbc.url}
jdbc.username=${b2b-order-service.jdbc.username}
jdbc.password=${b2b-order-service.jdbc.password}

b2b-account-service/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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javacode2018</groupId>
    <artifactId>b2b-account-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.javacode2018</groupId>
            <artifactId>b2b-account-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <properties>
        <!-- 指定資源文件複製過程中採用的編碼方式 -->
        <encoding>UTF-8</encoding>
    </properties>

    <!-- 配置多套環境 -->
    <profiles>
        <!-- 開發環境使用的配置 -->
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <property>
                    <name>env</name>
                    <value>env_dev</value>
                </property>
            </activation>
            <build>
                <filters>
                    <filter>../../config/dev.properties</filter>
                </filters>
            </build>
        </profile>
        <!-- 測試環境使用的配置 -->
        <profile>
            <id>test</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>env_test</value>
                </property>
            </activation>
            <build>
                <filters>
                    <filter>../../config/test.properties</filter>
                </filters>
            </build>
        </profile>
        <!-- 線上環境使用的配置 -->
        <profile>
            <id>prod</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>env_prod</value>
                </property>
            </activation>
            <build>
                <filters>
                    <filter>../../config/prod.properties</filter>
                </filters>
            </build>
        </profile>
    </profiles>

    <build>
        <resources>
            <resource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/main/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/test/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </testResource>
        </testResources>
    </build>

</project>

b2b-order-service/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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.javacode2018</groupId>
    <artifactId>b2b-order-service</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>b2b-account-api</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>b2b-order-api</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <properties>
        <!-- 指定資源文件複製過程中採用的編碼方式 -->
        <encoding>UTF-8</encoding>
    </properties>

    <!-- 配置多套環境 -->
    <profiles>
        <!-- 開發環境使用的配置 -->
        <profile>
            <id>dev</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <property>
                    <name>env</name>
                    <value>env_dev</value>
                </property>
            </activation>
            <build>
                <filters>
                    <filter>../../config/dev.properties</filter>
                </filters>
            </build>
        </profile>
        <!-- 測試環境使用的配置 -->
        <profile>
            <id>test</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>env_test</value>
                </property>
            </activation>
            <build>
                <filters>
                    <filter>../../config/test.properties</filter>
                </filters>
            </build>
        </profile>
        <!-- 線上環境使用的配置 -->
        <profile>
            <id>prod</id>
            <activation>
                <property>
                    <name>env</name>
                    <value>env_prod</value>
                </property>
            </activation>
            <build>
                <filters>
                    <filter>../../config/prod.properties</filter>
                </filters>
            </build>
        </profile>
    </profiles>

    <build>
        <resources>
            <resource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/main/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <!-- 指定資源文件的目錄 -->
                <directory>${project.basedir}/src/test/resources</directory>
                <!-- 是否開啟過濾替換配置,默認是不開啟的 -->
                <filtering>true</filtering>
            </testResource>
        </testResources>
    </build>

</project>

見證奇迹的時刻來了。

執行下面命令:

D:\code\IdeaProjects\b2b>mvn clean package -pl :b2b-account-service,:b2b-order-service -Pdev
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO]
[INFO] b2b-account-service                                                [jar]
[INFO] b2b-order-service                                                  [jar]
[INFO]
[INFO] ----------------< com.javacode2018:b2b-account-service >----------------
[INFO] Building b2b-account-service 1.0-SNAPSHOT                          [1/2]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-account-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-account-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-account-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-account-service ---
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-account-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-account\b2b-account-service\target\b2b-account-service-1.0-SNAPSHOT.jar
[INFO]
[INFO] -----------------< com.javacode2018:b2b-order-service >-----------------
[INFO] Building b2b-order-service 1.0-SNAPSHOT                            [2/2]
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ b2b-order-service ---
[INFO] Deleting D:\code\IdeaProjects\b2b\b2b-order\b2b-order-service\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ b2b-order-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ b2b-order-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ b2b-order-service ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\code\IdeaProjects\b2b\b2b-order\b2b-order-service\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ b2b-order-service ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ b2b-order-service ---
[INFO] No tests to run.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ b2b-order-service ---
[INFO] Building jar: D:\code\IdeaProjects\b2b\b2b-order\b2b-order-service\target\b2b-order-service-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for b2b-account-service 1.0-SNAPSHOT:
[INFO]
[INFO] b2b-account-service ................................ SUCCESS [  2.510 s]
[INFO] b2b-order-service .................................. SUCCESS [  0.257 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.026 s
[INFO] Finished at: 2019-11-21T20:11:32+08:00
[INFO] ------------------------------------------------------------------------

看一下兩個模塊target/classes下面jdbc.properties內容,如下圖:

使用了dev環境的配置,dev環境中處理資源文件替換的時候採用了config/dev.properties文件的內容,這部分配置如下,重點在於build->filters元素

<profile>
    <id>dev</id>
    <activation>
        <activeByDefault>true</activeByDefault>
        <property>
            <name>env</name>
            <value>env_dev</value>
        </property>
    </activation>
    <build>
        <filters>
            <filter>../../config/dev.properties</filter>
        </filters>
    </build>
</profile>

我們再使用prod環境看一下效果,執行下面命令:

mvn clean package -pl :b2b-account-service,:b2b-order-service -Pprod

效果圖如下:

感受一下,這次使用了b2b/config/prod.properties文件的內容對資源文件進行了替換,這次將所有配置的信息集中在config目錄的幾個文件中進行處理了,對於運維和開發來說都非常方便了。

profile元素更強大的功能

profile元素可以用於對不同環境的構建進行配置,project中包含的元素,在profile元素中基本上都有,所以profile可以定製更複雜的構建過程,不同的環境依賴的構件、插件、build過程、測試過程都是不一樣的,這些都可以在profile中進行指定,也就是說不同的環境所有的東西都可以通過profile元素來進行個性化的設置,這部分的功能有興趣的大家可以自己去研究一下,截個圖大家感受一下:

從上圖中可以看出這些屬性都可以根據環境進行定製的。

還是那句話,上面這些用法大家會經常用到的,建議大家下去了多練練。看和操作,所獲取到的是不能比的,看的過程中可能覺得一切都知道了,但是實際操作就不一樣了,可能中間會遇到各種問題,然後自己會想辦法解決這些問題,領會和學到的東西是不一樣的!

Maven系列目錄

更多好文章

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

分類
發燒車訊

傳蘋果電動汽車將採用韓國公司的電池技術

根據行業消息,蘋果近期與一家韓國電池開發商簽署了保密協議,聯合為代號為“泰坦”的汽車專案開發電池。從今年初開始,他們一直在韓國做行政工作。一名蘋果員工一直在這家韓國公司進行參觀活動,他屬於與蘋果電動汽車電池開發相關的部門。  
  業界認為,這家韓國公司並不是唯一一家負責蘋果電池開發的公司。不過,有消息稱,儘管蘋果從一開始就從完全不同的設計、功能以及性能角度來開發電池,但是他們仍舊一直在挖掘創新技術。業界相信,蘋果專注于開發出只能存在於蘋果自動駕駛汽車的創新電池技術。   這家韓國電池開發商由大約20名電池專家組成,持有空芯電池的國際專利技術。這些電池是圓柱形鋰離子二次電池,有兩根手指那麼厚,不同於其它空芯電池。蘋果並未選擇當前電動汽車普遍使用的標準圓形或矩形電池,但計畫根據韓國公司的空芯電池技術為其電動汽車開發自主電池。   文章來源:鳳凰科技

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

分類
發燒車訊

蘋果傳將攜手韓廠研發電動車用電池

蘋果公司持續擴大業務範圍,除新成立的蘋果能源(Apple Energy)成功取得售電許可外,市場上關注度十足的蘋果電動車專案「泰坦計畫」(Project Titan)也時常傳出新消息。近期傳言蘋果將與南韓某企業合作,運用該南韓公司的電池專利,攜手開發電動車用電池。

根據日本蘋果情報網站iPhone Mania、南韓媒體ET News 等報導,蘋果看上某家南韓廠商所取得的鋰電池專利,打算與該廠合作開發電動車用電池。被看上的鋰電池專利技術,電池中央部位採中空設計,可使空氣流通來冷卻電池,等同降低冷卻系統的需求,騰出更多空間來增加電池容量。

日、韓媒體並未披露可能將與蘋果合作的韓廠名稱,但美國MacRumors 透剁歐洲專利局得知,這款「中央中空」的電池是由一家稱為Orange Power 的南韓廠商取得。該廠係一小廠,員工人數僅33人,其中多數為研發人員。

蘋果電動車計畫自曝光以來即備受矚目,但至今仍然只聞樓梯響。據了解,目前共有約1,000人參與蘋果電動車企劃,且蘋果已在柏林設立秘密開發實驗室。MoneyDJ引述The Information網站的說法,表示蘋果電動車可能在2021年亮相;但也有分析師認為,蘋果電動車可能會步上蘋果電視的後塵,胎死腹中。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

分類
發燒車訊

續航力600公里的特斯拉 即將問世?

續航力是電動車最受關注的性能,而作為全球電動車龍頭廠商的特斯拉(Tesla),似乎也準備好要推出續航力更久的車款了。跟據了解,新的特斯拉電動車可能搭載100kW的電池,續航力最遠可達611公里。

《癮科技》中文版指出,德國監管機關的資料中可查到Model S與Model X的100D與P100D型號的相關資訊;而根據特斯拉為車款型號命名的邏輯,這可能暗示特斯拉將推出搭載100kW電池的車款。

100kW 的電池搭配Model S,預計最高續航里程可來到611公里,比90D的續航里程多了100公里以上。若搭配Model X,續航里程也可來到480 公里之多。這樣的續航力,將能有效減輕美國車主對駕駛特斯拉跨州旅行的疑慮。

(照片來源:Tesla 臉書專頁)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

分類
發燒車訊

從零開始搭建前後端分離的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的項目框架之十一Swagger使用一

 一.未使用Swagger狀況

  相信無論是前端開發人員還是後端開發人員,都或多或少都被接口文檔折磨過,前端經常抱怨後端給的接口文檔或與實際情況不一致。後端又覺得編寫及維護接口文檔會耗費不少精力,經常來不及更新。 其實無論是前端調用後端,還是後端調用後端,都期望有一個好的接口文檔。但是這個接口文檔對於程序員來說,就跟註釋一樣,經常會抱怨別人寫的代碼沒有寫註釋,然而自己寫起代碼起來,最討厭的,也是寫註釋。 所以僅僅只通過強制來規範大家是不夠的,隨着時間推移,版本迭代,接口文檔往往很容易就跟不上代碼了

 二.使用Swagger狀況

  Swagger 提供了一個可視化的UI頁面展示描述文件,其中包括接口的調用,接口所需參數(header,body,url.params),接口說明,參數說明等。接口的調用方、測試、項目經理等都可以在該頁面中對相關接口進行查閱和做一些簡單的接口請求。只要在項目框架搭建時,對Swagger 進行了配置,後面持續迭代的時候,只會花很小代價去維護代碼、接口文檔以及Swagger描述文件。因為一旦接口發生改變,程序重新部署,接口文檔會重新生成對應新的文檔。

 三.如何使用?

  在NetCore項目中怎麼去使用Swagger來生成接口文檔呢?

  首先在 webApi 啟動項目 上 右鍵 點擊管理Nuget程序包, 安裝  Swashbuckle.AspNetCore ,然後到  Startup 中添加引用  using Swashbuckle.AspNetCore.Swagger; 

  在ConfigureServices方法中添加以下代碼

            #region Swagger

            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new Info
                {
                    Version = "v1",
                    Title = "API Doc",
                    Description = "作者:Levy_w_Wang",
                    //服務條款
                    TermsOfService = "None",
                    //作者信息
                    Contact = new Contact
                    {
                        Name = "levy",
                        Email = "levy_w_wang@qq.com",
                        Url = "https://www.cnblogs.com/levywang"
                    },
                    //許可證
                    License = new License
                    {
                        Name = "tim",
                        Url = "https://www.cnblogs.com/levywang"
                    }
                });

                #region XmlComments

                var basePath1 = Path.GetDirectoryName(typeof(Program).Assembly.Location);//獲取應用程序所在目錄(絕對,不受工作目錄(平台)影響,建議採用此方法獲取路徑)
                //獲取目錄下的XML文件 显示註釋等信息
                var xmlComments = Directory.GetFiles(basePath1, "*.xml", SearchOption.AllDirectories).ToList();

                foreach (var xmlComment in xmlComments)
                {
                    options.IncludeXmlComments(xmlComment);
                }
                #endregion

                options.DocInclusionPredicate((docName, description) => true);

                options.IgnoreObsoleteProperties();//忽略 有Obsolete 屬性的方法
                options.IgnoreObsoleteActions();
                options.DescribeAllEnumsAsStrings();
            });
            #endregion

上面寫的循環是因為項目中可能有多個控制器類庫,為的是排除這種情況

接下來,再到 Configure 方法中添加:

            #region Swagger

            app.UseSwagger(c => { c.RouteTemplate = "apidoc/{documentName}/swagger.json"; });
            app.UseSwaggerUI(c =>
            {
                c.RoutePrefix = "apidoc";
                c.SwaggerEndpoint("v1/swagger.json", "ContentCenter API V1");
                c.DocExpansion(DocExpansion.Full);//默認文檔展開方式
            });

            #endregion

這裏使用了 RoutePrefix  屬性,為的是改變原始打開接口文檔目錄,原始路徑為 swagger/index.html ,現在為 /apidoc/index.html 

這個時候在需要輸出註釋的控制器類庫屬性 中設置如下信息,並添加上相關註釋

然後運行起來,打開本地地址加上  /apidoc/index.html  就可以看到效果,

特別提醒:如果打開下面這個界面能正常显示,但是提示  Fetch errorInternal Server Error v1/swagger.json  錯誤,說明有方法未指明請求方式,如 HttpGet HttpPost HttpPut 等,找到並指明,重新運行就正常了

 

  點擊方法右上角的 Try it out ,試下調用接口,然後點擊Exectue,執行查看結果,能得到後端方法返回結果就說明成功。

特別說明:有接口不需要展示出去的時候,可以在方法上添加屬性 Obsolete ,這樣就不會显示出來。 前提:有前面ConfigureServices中 後面的 忽略 有Obsolete 屬性的方法 設置才行!!!

 

 最後可以看到接口返回數據正常,並且也能看到接口響應請求嘛等等信息,一個接口應該返回的信息也都有显示。

 

總結:

本文從為開發人員手寫api文檔的痛楚,從而引申出Swagger根據代碼自動生成出文檔和註釋,

並且還可以將不需要的方法不显示等設置。然後進行了簡單的測試使用 。

但是!!一般後端方法都有token等驗證,需要在header中添加token、sid等字段來驗證用戶,保障安全性,

該設置將在下一章節中寫!

 下一章

以上若有什麼不對或可以改進的地方,望各位指出或提出意見,一起探討學習~

有需要源碼的可通過此 鏈接拉取 覺得還可以的給個 start 和點個 下方的推薦哦~~謝謝!

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

分類
發燒車訊

PostgreSQL空間數據庫創建備份恢復(PostGIS vs ArcGIS)

梯子

PostGIS

創建

安裝就不必介紹了,windows下使用安裝工具Application Stack Builder,選擇空間擴展PostGIS即可自動安裝

然後新建庫后,在庫中執行以下語句創建控件擴展

CREATE EXTENSION postgis

也可以創建數據庫時選擇postgis的模板庫創建

create database postgisdb template postgis_template;

新建數據庫后添加postgis擴展後會發現庫內public模式下函數序列觸發器等都會增加一些postgis相關功能
然後就可以通過PostGIS Shapefile and DBF Loader工具導入shp數據

備份

postgersql的備份恢復主要有

  1. 增量備份和基於時間點恢復(RITR)
  2. pg_dump和pg_dumpall進行轉儲,從SQL轉儲文件恢復
  3. 文件系統級別備份

這裏我們使用簡單,容易掌握的pg_dump命令,一般在安裝目錄bin下
pg_dump備份單庫,不導出角色和表空間相關信息

pg_dump -h localhost -U postgres postgisdb > D:\backup\postgisdb.bak

有一些參數選項可以參考(很多,具體不列了,執行help可以查看到)

pg_dump --help
恢復

恢復可以使用psql

psql -h localhost -U postgres -d postgisdb2 < D:\backup\postgisdb.bak

恢復時可以指定不同的數據庫,如果pg_dump時-C創建數據庫,那也可以不用先新建數據庫

postgis庫的恢復備份還是挺簡單的,所有的東西都在public下

ArcGIS

創建

ArcGIS要連接到postgresql,需要將postgresql安裝目錄lib下的libeay32.dll、libiconv-2.dll、libintl-8.dll、libpq.dll 和 ssleay32.dll拷貝到ArcGIS Desktop的安裝目錄bin下
將ArcGIS Desktop目錄DatabaseSupport\PostgreSQL下的st_geometry.dll拷貝到postgresql的lib下

使用ArcGIS工具箱中Create Enterprise Geodatabase工具創建SDE,完事後會在創建一個sde登陸角色並在庫中創建一個sde模式,包含諸多函數序列管理表等。(注意:ArcGIS雖然可以在系統庫postgres中創建SDE擴展,然並連不上,ArcGIS不允許連接訪問系統數據庫

然後ArcGIS可以連接該數據庫,並且進行空間數據管理操作。(注意:默認ArcGIS創建空間數據,只能創建在和登陸用戶同名的模式下

備份

我們可以向上面PostGIS備份恢復一樣,直接備份整個庫

恢復

如果恢復至同名數據庫,像上面恢復是沒有問題的
但如果數據庫改名了,則會有驚喜發生,ArcGIS管理空間報底層gdb_release之類的錯誤,同樣的問題不止恢復庫時,修改數據庫名稱也不像其他庫那麼隨心所欲,以含SDE擴展的庫為模板創建新庫也會有問題

ArcGIS SDE未見文檔介紹內部結構邏輯,只能猜測大概,或不準確,願聞其詳

ArcSDE空間數據創建時會在SDE管理表裡註冊相關信息,比如空間參考,列啊,表的唯一標識等,便於它做數據管理、版本控制

修改庫名后,ArcSDE管理就出問題,主要是一些註冊項,安裝SDE時也會把該庫的信息註冊到SDE管理表中去,所以新庫名,它就不認識了

如果修改了庫名,我們找到以下錶

select * from sde.gdb_items
you need modify : name physicalname path etc...

update sde.sde_table_registry set database_name='testdb';
update sde.sde_column_registry set database_name='testdb';
update sde.sde_geometry_columns set f_table_catalog='testdb';
update sde.sde_raster_columns set database_name='testdb';
update sde.sde_layers set database_name='testdb';

然後就一切正常

當然我們建議不輕易改庫名

這就是商業軟件,足夠強大不夠靈活,封裝和靈活總會互相博弈

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

分類
發燒車訊

paper sharing :學習特徵演化的數據流

特徵演化的數據流

    數據流學習是近年來機器學習與數據挖掘領域的一個熱門的研究方向,數據流的場景和靜態數據集的場景最大的一個特點就是數據會發生演化,關於演化數據流的研究大多集中於概念漂移檢測(有監督學習),概念/聚類演化分析(無監督學習),然而,人們往往忽略了一個經常出現的演化場景:特徵演化。大多數研究都考慮數據流的特徵空間是固定的,然而,在很多場景下這一假設並不成立:例如,當有限壽命傳感器收集的數據被新的傳感器替代時,這些傳感器對應的特徵將發生變化。

    今天要分享的文章出自周志華的實驗室《Learning with Feature Evolvable Streams》(NIPS 2017),它提出了一個新的場景,即在數據流中會有特徵消亡也會有新特徵出現。當出現新的特徵空間時,我們並不直接拋棄之前學到的模型並在新的數據上重新創建模型,而是嘗試恢復消失的特徵來提升模型的表現。具體來說,通過從恢復的特徵和新的特徵空間中分別學習兩個模型。為了從恢復的特徵中獲得提升,論文中提出了兩種集成策略:第一種方法是合併兩個模型的預測結果;第二種是選擇最佳的預測模型。下面我們具體來理解特徵演化數據流以及論文中提出的一些有趣的方法吧~

paper link:

 

什麼是特徵演化數據流?

    在很多現實的任務中,數據都是源源不斷收集的,關於數據流學習的研究近年來受到越來越多的關注,雖然已經有很多有效的算法針對特定的場景對數據流進行挖掘,但是它們都基於一個假設就是數據流中數據的特徵空間是穩定的。不幸的是,這一假設在很多場景下都不滿足。針對特徵演化的場景,最直接的想法就是利用新的特徵空間的數據學習一個新的模型,但是這一方法有很多問題:首先,當新的特徵剛出現的時候,只有很少的數據樣本來描述這些信息,訓練樣本並不足夠去學習一個新的模型;其次,包含消失特徵的舊模型被直接丟棄了,其中可能包含對當前數據有用的信息。論文中定義了一種特徵演化數據流的場景:一般情況下,特徵不會任意改變,而在一些重疊時期,新特徵和舊特徵都存在,如下圖所示:

    其中,T1階段,原始特徵集都是有效的,B1階段出現了新的特徵集,T2階段原始特徵集消失,只有新的特徵集。

    論文提出的方法是通過使用重疊(B1)階段來發現新舊特徵之間的關係,嘗試學習新特徵到舊特徵的一個映射,這樣就可以通過重構舊特徵並使用舊模型對新數據進行預測

問題描述

    論文中着重解決的是分類和回歸任務,在每一輪學習過程中,對每一個實例進行預測,結合它的真實標籤會得到一個loss(反映預測和真實標籤的差異),我們將上面提到的T1+B1+T的過程稱為一個周期,每個周期中只包含兩個特徵空間,所以,之後的研究主要關注一個周期內的模型的學習,而且,我們假設一個周期內的舊特徵會同時消失。定義Ω1和Ω2分別表示兩個特徵空間S1和S2上的線性模型,並定義映射,定義第i維特徵在第t輪的預測函數為線性模型,。損失函數是凸的,最直接的方式是使用在線梯度下降來求解w,但是在數據流上不適用。

 

方法介紹

    上文提到的基本算法的主要限制是在第1,…T1輪學習的模型在T1+1,…T1+T2時候被忽略了,這是因為T1之後數據的特徵空間改變了,我們無法直接應用原來的模型。為了解決這一問題,我們假設新舊特徵空間之間有一種特定的關係:,我們嘗試通過重疊階段B1來學習這種關係。學習兩組特徵之間的關係的方法很多,如多元回歸,數據流多標籤學習等。但是在當前的場景下,由於重疊階段特別短,學習一個複雜的關係模型是不現實的。所以我們採用線性映射來近似。定義線性映射的係數矩陣為M,那麼在B1階段,M的估計可以基於如下的目標方程:

M的最優解可以解得:

    然後,當我觀測到S2空間得數據,就可以通過M將其轉化到S1空間,並應用舊模型對其進行預測。

除了學習這個關係映射之外,我們得算法主要包括兩個部分:

  1. 在T1-B1+1,…T1階段,我們學習兩個特徵空間之間得關係;

  2. 在T1之後,我們使用新特徵空間的數據轉化后的原特徵空間數據,持續更新舊模型以提升它的預測效果,然後集成兩個模型進行預測。

 

預測結果集成

    論文中提出兩種集成方法,第一種是加權組合,即將兩個模型的預測結果求加權平均,權重是基於exponential of the cumulative loss。

其中

    這種權重的更新規則表明,如果上一輪模型的損失較大,下一輪模型的權值將以指數速度下降,這是合理的,可以得到很好的理論結果。

    第二種集成方法是動態選擇。

    上面提到的組合的方法結合了幾個模型來提升整體性能,通常來說,組合多個分類器的表現會比單分類器的效果要好,但是,這基於一個重要的假設就是每個基分類器的表現不能太差(如,在Adaboost中,基分類器的預測精度不應低於0.5)。然而在這個問題中,由於新特徵空間剛出現的時候訓練集較小,訓練的模型不好,因此可能並不適合用組合的方法來預測,相反,用動態選擇最優模型的方法反而能獲得好的效果。

有趣的靈魂在等你長按二維碼識別

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

分類
發燒車訊

Go 多變量賦值時注意事項

說到多變量賦值時,先計算所有相關值,然後再從左到右依次賦值,但是這個規則不適用於python
我們來看一例:

package main

import "fmt"

func main() {
    data, i := [3]string{"喬幫主","慕容復","鳩摩智"}, 0
    i, data[i] = 2, "枯榮大師"
    fmt.Println(i, data)
}

輸出結果:

2 [枯榮大師 慕容復 鳩摩智]  

有的朋友會認為,結果不應該是這樣么?(但是python下輸出的結果卻是下面的)?

2 [喬幫主 慕容復 枯榮大師]

事實並如此,我們來看賦值順序這段的理解:

1     data, i := [3]string{"喬幫主","慕容復","鳩摩智"}, 0
2     i, data[i] = 2, "枯榮大師" //注意原則:先計算所有相關值,然後再從左到右依次賦值
3     // 這裏變量i 的順序其實是(i = 0,因為上一行的變量i是0) -> (然後 i = 2), (data[i] 此時取的值是data[0],而不是data[2],也就是data[0] = 枯榮大師)
4     fmt.Println(i, data) //所以這裏最終 輸出 i=2,[枯榮大師 慕容復 鳩摩智]

同樣的多變量賦值卻不適用於python.

data,i=["喬幫主", "慕容復", "鳩摩智"],0
i, data[i] = 2, "枯榮大師" # 注意這裏data[i] 已經是 data[2]了,即data[2]="枯榮大師"
print(i,data) # 輸出 2 ['喬幫主', '慕容復', '枯榮大師']

另外:我們要注意重新賦值與定義新同名變量的區別:再看一例:

package main

func main() {
    name := "喬幫主"
    println(&name)
    name, age := "鳩摩智", 30 // 重新賦值: 與前 name 在同層次的代碼塊中,且有新的變量被定義。
    println(&name, age)    // 通常函數多返回值 err 會被重複使用。
    {
        name, weight := "清風揚", 50 // 定義新同名變量: 不在同層次代碼塊。
        println(&name, weight)
    }
}

輸出:

0xc00002bf78
0xc00002bf78 30
0xc00002bf68 50

注意:因個人機器不同,大家返回的內存引用地址可能和我的不一樣,但是 這步是重點。重點在這裏:
同層級相同變量的賦值,內存地址並不會改變。不同層級相同變量的賦值,其實是定義了一個新同名變量,也就是大家看到的第三行內存地址變了。
接着我們再看有點意思的一段代碼(大家來找茬):

package main

func main() {
    name := "喬幫主"
    println(&name)
    name, age := "鳩摩智", 30 // 重新賦值: 與前 name 在同 層次的代碼塊中,且有新的變量被定義。
    println(&name, age)    // 通常函數多返回值 err 會被重複使用。

    name, weight := 100, 50 // 定義新同名變量: 不在同 層次代碼塊。
    println(&name, weight, age)

}

輸出:

cannot use 100 (type int) as type string in assignment

原因很明顯,因為上面:name := “喬幫主” 已經隱試滴申明了name 是字符串,等同於 var name string. 同層級再次賦值100為整形。這是不允許滴,

但是:重點來了,我們稍改下:

package main

func main() {
    name := "喬幫主"
    println(&name)
    name, age := "鳩摩智", 30 // 重新賦值: 與前 name 在同 層次的代碼塊中,且有新的變量被定義。
    println(&name, age)    // 通常函數多返回值 err 會被重複使用。
    {
        name, weight := 100, 50 // 定義新同名變量: 不在同層次代碼塊。
        println(&name, weight, age)
    }
}

區別就是層級發生了變化,因為{}裏面的name已經是新的變量了。
好啦,到此介紹結束了。博友們有關golang變量使用中遇到的各種奇怪的“坑”,請留下寶貴滴足跡,歡迎拍磚留言.

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

※評比前十大台北網頁設計台北網站設計公司知名案例作品心得分享

※智慧手機時代的來臨,RWD網頁設計已成為網頁設計推薦首選

分類
發燒車訊

【併發編程】Java中的原子操作

什麼是原子操作

原子操作是指一個或者多個不可再分割的操作。這些操作的執行順序不能被打亂,這些步驟也不可以被切割而只執行其中的一部分(不可中斷性)。舉個列子:

//就是一個原子操作
int i = 1;

//非原子操作,i++是一個多步操作,而且是可以被中斷的。
//i++可以被分割成3步,第一步讀取i的值,第二步計算i+1;第三部將最終值賦值給i
i++;

Java中的原子操作

在Java中,我們可以通過同步鎖或者CAS操作來實現原子操作。

CAS操作

CAS是Compare and swap的簡稱,這個操作是硬件級別的操作,在硬件層面保證了操作的原子性。CAS有3個操作數,內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什麼都不做。Java中的sun.misc.Unsafe類提供了compareAndSwapIntcompareAndSwapLong等幾個方法實現CAS。

另外,在jdk的atomic包下面提供了很多基於CAS實現的原子操作類,見下圖:

下面我們就使用其中的AtomicInteger來看看怎麼使用這些原子操作類。

package com.csx.demo.spring.boot.concurrent.atomic;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerDemo {

    private static int THREAD_COUNT = 100;

    public static void main(String[] args) throws InterruptedException {


        NormalCounter normalCounter = new NormalCounter("normalCounter",0);
        SafeCounter safeCounter = new SafeCounter("safeCounter",0);
        List<Thread> threadList = new ArrayList<>();

        for (int i = 0; i < THREAD_COUNT ; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 10000; j++) {
                        normalCounter.add(1);
                        safeCounter.add(1);
                    }
                }
            });
            threadList.add(thread);
        }

        for (Thread thread : threadList) {
            thread.start();
        }
        for (Thread thread : threadList) {
            thread.join();
        }
        System.out.println("normalCounter:"+normalCounter.getCount());
        System.out.println("safeCounter:"+safeCounter.getCount());
    }


    public static class NormalCounter{
        private String name;
        private Integer count;

        public NormalCounter(String name, Integer count) {
            this.name = name;
            this.count = count;
        }

        public void add(int delta){
            this.count = count+delta;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getCount() {
            return count;
        }

        public void setCount(Integer count) {
            this.count = count;
        }
    }

    public static class SafeCounter{
        private String name;
        private AtomicInteger count;

        public SafeCounter(String name, Integer count) {
            this.name = name;
            this.count = new AtomicInteger(count);
        }

        public void add(int delta){
            count.addAndGet(delta);
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getCount() {
            return count.get();
        }

        public void setCount(Integer count) {
            this.count.set(count);
        }
    }

}

上面的代碼中,我們分別創建了一個普通的計數器和一個原子操作的計數器(使用AtomicInteger進行計數)。然後創建了100個線程,每個線程進行10000次計數。理論上線程執行完之後,計數器的值都是1000000,但是結果如下:

normalCounter:496527
safeCounter:1000000

每次執行,普通計數器的值都是不一樣的,而使用AtomicInteger進行計數的計數器都是1000000。

CAS操作存在的問題

  • ABA問題:因為CAS需要在操作值的時候檢查下值有沒有發生變化,如果沒有發生變化則更新,但是如果一個值原來是A,變成了B,又變成了A,那麼使用CAS進行檢查時會發現它的值沒有發生變化,但是實際上卻變化了。ABA問題的解決思路就是使用版本號。在變量前面追加上版本號,每次變量更新的時候把版本號加一,那麼A-B-A 就會變成1A-2B-3A。

從Java1.5開始JDK的atomic包里提供了一個類AtomicStampedReference來解決ABA問題。這個類的compareAndSet方法作用是首先檢查當前引用是否等於預期引用,並且當前標誌是否等於預期標誌,如果全部相等,則以原子方式將該引用和該標誌的值設置為給定的更新值。

  • 循環時間長開銷大:自旋CAS如果長時間不成功,會給CPU帶來非常大的執行開銷。如果JVM能支持處理器提供的pause指令那麼效率會有一定的提升,pause指令有兩個作用,第一它可以延遲流水線執行指令(de-pipeline),使CPU不會消耗過多的執行資源,延遲的時間取決於具體實現的版本,在一些處理器上延遲時間是零。第二它可以避免在退出循環的時候因內存順序衝突(memory order violation)而引起CPU流水線被清空(CPU pipeline flush),從而提高CPU的執行效率。

  • 只能保證一個共享變量的原子操作:當對一個共享變量執行操作時,我們可以使用循環CAS的方式來保證原子操作,但是對多個共享變量操作時,循環CAS就無法保證操作的原子性,這個時候就可以用鎖,或者有一個取巧的辦法,就是把多個共享變量合併成一個共享變量來操作。比如有兩個共享變量i=2,j=a,合併一下ij=2a,然後用CAS來操作ij。從Java1.5開始JDK提供了AtomicReference類來保證引用對象之間的原子性,你可以把多個變量放在一個對象里來進行CAS操作。

使用鎖來保證原子操作

還是以上面的列子為列,普通的計數器我們只需要在計數方法上加鎖就行了:

public synchronized void  add(int delta){
  this.count = count+delta;
}

執行結果如下:

normalCounter:1000000
safeCounter:1000000

兩個計數器都能拿到正確的結果

CPU是怎麼實現原子操作的

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

分類
發燒車訊

三個月(敏捷)項目收穫

 

 

項目背景

客戶已有運行多年的官網老站(PC端),想在今年對老站進行一次UI全面更新、功能全部平移的升級,對接新的運營後端,然後建立官網小程序端且與官網PC端進行聯動,使得品牌自有渠道能夠更加全面化。

 

挑戰

  • 時間緊。五月份進行Inception Workshop,確定項目交付範圍與架構方案。官網六月初開始開發,小程序八月份開始開發,整個項目九月中旬必須上線。
  • 系統集成和數據遷移。系統需要對接客戶的CRM,對接3個服務商,需要對老官網歷史數據(訂單、會員等)進行遷移。
  • 多團隊溝通。小程序設計稿由第三方提供,因此多出了溝通、確認的時間,以及把控第三方交付的時間,以避免交付進度的影響。

 

迭代計劃

Inception Workshop一結束,差不多就開始整理整個項目涉及的故事和技術卡,按照兩周一迭代進行迭代計劃安排並與客戶確認,每個迭代第一周周三安排跟客戶showcase上一周的預定的交付結果,得到反饋並安排進行改進。官網項目比較順利,改造自定義了一下SSR框架就能開始進行開發,並且因為歷史原因,還能享受到上一個項目遺留的一些福利,當然也少不了一些坑。

小程序的時間比較緊,相當於整個複製了一遍官網的功能,主要是前端任務,後端可以復用官網後端,因此一開始就給團隊同學同步到整個項目的情況,讓大家有一個大概的心理準備。然後就是與官網類似的處理,整個交付內容進行迭代排期並與客戶確認,前期盡量能多做一些,避免後期怎麼努力都無法完成的囧鏡。

 

項目進行時

整個項目的過程中,PM會根據迭代完成情況靈活的找外援加入項目進行支援,以免交付延期。每日的站會(Standup Meeting)更新,讓團隊能對當前進度有一個大概的了解以及同步一些突發信息。定期的回顧會議(Retrospective Meeting)能暴露團隊內部問題,將風險扼殺於苗頭,鼓勵能為團隊帶來正向幫助的行為,及時停止不好的做法。

迭代會議(IPM)能讓團隊對下一個迭代具體要做的事情有一個詳細的了解,進行大致的估點,以便check開發進度情況。技術人員定期的CodeReview成為一個大家交流的時段,發現風險,指出問題,互相提高,還可以幫助新人快速的融入團隊。

根據團隊內部人員情況,可以定期進行一對一溝通,了解個人訴求或是給與近況反饋都是一個不錯的渠道。TL應考慮團隊內部人員提升自己的訴求,在一些安排上給與傾斜和鼓勵,發現問題也需要提前制止。

 

不足之處

  • 後期對卡牆(Jira)的管理鬆懈。導致有些問題反覆修改,且丟失context
  • 項目對運營後台有一些的定製化配置,沒有提前準備運營需要了解的後台操作資料和培訓,導致後期花費大量精力幫助運營進行後台配置與更新
  • 人員(QA)變動頻繁。公司處於高速發展階段,項目經歷了4個QA,因此有些context可能丟失,測試不到位,導致項目上線出了一些低級問題。比如上線后發現部分瀏覽器有支付兼容問題
  • 甲乙方定位太角色化,不能站在專業角度評估客戶需求(項目做完感覺都一樣,客戶是爸爸)
  • 與第三方合作交付產物管控不到位,導致第三方設計稿的延遲影響到我們的交付計劃
  • 與客戶溝通的需求,後面有一些沒有進行郵件確認,導致交付驗收階段因一些需求上的問題產生不愉快(這個完全沒必要的)
  • 對第三方系統的了解不充分和集成系統的需求整理不清晰導致後續一系列的開發、測試都不到位,以致上線出了不可控的問題

 

項目總結

  • 提前評估項目的風險點,且在項目進行過程中持續維護,後期安排足夠的時間進行調研與分析
  • 與第三方合作一定要有自己的規劃,並且將定好的規劃提前與第三方確認時間,然後派人提前專門細緻的了解第三方需求詳細點,確定好具體的業務場景,再來規劃己方與第三方的具體集成的點。此外,在進行的過程中,還應注意定時檢查合作進度,管控風險
  • 與客戶溝通的所有需求都要進行郵件的二次確認,一個是能夠對所有需求來源有所記錄,另一個是能避免後面的不必要的消耗
  • 開發管理不能鬆懈,盡量做到所有的改動都能有卡,能夠進行追溯
  • 對後期交付時所需要的資料提前準備,對需要進行培訓的人員提前約好時間進行溝通培訓

在前端這塊的管理上,做的還不夠。前期經常codereview,然後效果都還不錯,讓我有了一些錯覺就是當前團隊趨於穩定,中後期即便是加班比較多,大家氣氛這塊我覺得都還好。不過在項目後期的時候,有些疏於管理,然後大家有些人也被分配到了其他項目,和同事們的交流不夠,沒有及時的顧及到一些個人情緒,這塊是可以加強的。

作為一個Lead,不論同事是否還在一個項目都應該及時的去了解近況,給與自己力所能及的幫助,這樣才能產生向心力,以幫助一些比較迷茫的同學找到方向,看見燈塔。

整個項目時間不長,得失還是挺多的,不論是管理還是技術上,都會有一些心得。然後項目的ROI還不錯,得到公司領導的肯定,最後客戶那邊的反饋也還不錯,算是對大家努力的一種認可。

ps: 及時總結,靜心沉澱;如風少年,砥礪前行。

如想了解更多,請移步

歡迎關注我的公眾號 “和F君一起xx”

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!