實習日記-工具框架-Maven複習

我的博客:zhenganwen.topjava

安裝和配置

環境變量

將解壓後的bin目錄配置到path中。主要是mvn命令,此命令的生命週期(後一個命令的執行將致使其前面的全部命令先執行一遍)以下:web

  • mvn compile,根據src/main/java目錄編譯生成包含字節碼的target目錄
  • mvn test,執行src/test/java目錄下的全部測試用例
  • mvn package,將此項目打包(jarwar)放至target目錄下
  • mvn install,將此項目打包後的文件放至本地倉庫中

mvn clean則會將本項目的target目錄清楚,有時你拿到的不是一個乾淨的maven項目(即別人編譯、打包過),爲了不目標文件因運行環境不一樣而致使運行出錯,建議先mvn clean並從新構建一下spring

配置文件

maven只有一個配置文件,即maven_home/conf/settings.xmlexpress

本地倉庫

默認將C盤下用戶主目錄做爲本地倉庫的位置,若是你不想佔C盤空間,能夠設置以下:apache

<!-- localRepository | The path to the local repository maven will use to store artifacts. | | Default: ${user.home}/.m2/repository <localRepository>/path/to/local/repo</localRepository> -->
<localRepository>D:\Software\Maven\mvn_repo</localRepository>
複製代碼

中心倉庫鏡像

因爲maven的中心倉庫部署在國外的服務器上(下載依賴時若是在本地倉庫中沒有找到該依賴則會去中心倉庫),網速不佳,所以可使用國內的阿里雲鏡像:api

<mirrors>
    <!-- mirror | Specifies a repository mirror site to use instead of a given repository. The repository that | this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used | for inheritance and direct lookup purposes, and must be unique across the set of mirrors. | <mirror> <id>mirrorId</id> <mirrorOf>repositoryId</mirrorOf> <name>Human Readable Name for this Mirror.</name> <url>http://my.repository.com/repo/path</url> </mirror> -->

    <mirror>  
        <id>alimaven</id>  
        <mirrorOf>central</mirrorOf>  
        <name>aliyun maven</name> 
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>  

</mirrors>
複製代碼

用Maven搭建一個web工程

以下使用IDEA建立一個帶有骨架(在src/java/main/下添加了一個webapp用於存放視圖文件)的Web工程tomcat

而後咱們建立Servlet,發現HttpServelt報紅找不到該類,說明servlet相關jar包沒有引入,因而在pom.xml中添加servletjsp依賴:服務器

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
    </dependency>
</dependencies>
複製代碼

做用域

接着,能夠在項目根目錄的命令行下鍵入tomcat:run運行(maven默認內嵌了一個tomcat6),你會發現報錯:本身寫的Servlet沒法轉換成HttpServelt,這是由於tomcat應用已依賴了servlet-apijsp-api,你在pom中又引入了一次,致使項目中這兩個依賴都有兩個jar包而產生了衝突。app

因爲咱們只須要咱們在pom中引入的servlet-apijsp-api幫助咱們度過編譯期,而運行期不要將其編入target使用內嵌tomcat中的就能夠了,所以咱們能夠將這兩個依賴的生命週期(scope)設置爲providewebapp

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
複製代碼

如此咱們寫的servletjsp即可以正常運行了。

若是不寫scope則默認爲compile,即做用域編譯期、測試期、運行期;test則僅做用於測試代碼/src/test/java的編譯和運行(典型的如junit);runtime表示被依賴項目無需參與編譯,但後期的測試和運行須要其參與,如jdbc驅動

注:若是你使用的JDK是Java8,仍然會拋出異常,由於tomcat6不兼容Java8。解決以下

Maven插件

有不少Maven插件能夠集成進來幫助咱們快速構建應用,好比上述tomcat6不兼容Java8的問題,咱們就能夠集成tomcat7插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <port>8888</port>
            </configuration>
        </plugin>
    </plugins>
</build>
複製代碼

如此,鍵入tomcat7:run命令就能使該項目運行在端口爲8888tomcat7上,而鍵入tomcat:run命令則仍將此項目運行在默認8080端口的tomcat6上。

依賴衝突

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
複製代碼

當你引入上述依賴時,因爲spring-context自身依賴5.0.2.RELEASE版本的core、beans、expression、aop等依賴,又因爲maven的傳遞性,當前項目也會引入這些依賴。此時,context稱爲直接依賴,後者稱爲傳遞依賴。

若是此時你再手動引入一個4.2.4.RELEASE版本的beans依賴:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
    <scope>compile</scope>
</dependency>
複製代碼

由於contextbeans都依賴core,那麼Maven間接依賴進來的core取哪一個版本呢?

原則一:先進先留原則

若是兩個直接依賴引入了兩個不一樣版本的相同依賴,在pom中書寫在前的將被保留。

也即,若是書寫以下:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
    <scope>compile</scope>
</dependency>
複製代碼

那麼引入的將是5.0.2.RELEASE版本的spring-core,不然將二者的書寫順序顛倒:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
複製代碼

引入的spring-core就是4.2.4.RELEASE版本的了。

原則二:依賴鏈短者保留

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
複製代碼

如上,不管spring-beansspring-context的書寫順序如何,引入的spring-core均以第15行的5.0.2.RELEASE爲準,由於經過依賴傳遞造成的依賴鏈最短。

原則三:使用exclusion排除依賴【推薦】

當發生依賴衝突時,咱們能夠將全部不想要的依賴經過exclusion顯式聲明的方式排除掉,這樣最爲直觀。如,排除掉4.2.4版本的spring-core

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-beans</artifactId>
    <version>4.2.4.RELEASE</version>
    <scope>compile</scope>
    <exclusions>
        <exclusion>
            <artifactId>org.springframework</artifactId>
            <groupId>spring-core</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
複製代碼

其餘標籤

dependencyManagement

dependencyManager用來統一管理版本號,讓子項目中引用一個依賴而不用顯示的列出版本號。Maven會沿着父子層次向上走,直到找到一個擁有dependencyManagement元素的項目,而後它就會使用在這個dependencyManagement元素中指定的版本號。這樣,一旦整個系統須要迭代升級,只需將定義在父項目的dependencyManagement中的版本號更換便可實現其全部子項目的依賴升級。

properties

定義一些鍵值對,已達到複用、減小修改的目的。

父子工程

父工程一般不存放源代碼,僅僅起到一個聚合的做用,將相關聯的一些模塊聚合在一塊兒。須要注意一下幾點:

  • 父工程的pom中的package必須是pom

  • 父工程一般經過定義dependencyManagement來控制子模塊的依賴的版本號統一

  • 父工程可在dependency中定義各子模塊均可能用到的依賴,這些依賴會自動被子模塊繼承,也即子模塊可省略在其pom中對這些依賴的引入

  • 各子模塊雖然繼承同一父工程,但彼此之間沒有任何直接關聯關係,若是模塊A須要用到模塊B的功能,則需現將模塊Bmvn install到本地倉庫,而後在模塊A的pom中引入模塊B的座標。

    注:對於任何maven工程,不管是父工程仍是子模塊,要想其編譯成功,其全部依賴必需要能在本地倉庫或遠程倉庫中找獲得

建立子模塊的方法:右鍵父工程,選擇new module。子模塊能夠在父工程的目錄下,也能夠和父工程同一目錄,這沒有任何影響。是不是父子工程須要看父工程pom中的module定義和子模塊pom中的parent定義,子模塊的parent中寫父工程的groupId、artifactId、version,本身的groupIdversion都將繼承父工程的,只需自定義artifactId

相關文章
相關標籤/搜索