天天看点

maven的optional与provided的区别,deploy小技巧前言scope providedoptional总结

optional与provided

  • 前言
  • scope provided
  • optional
  • 总结

前言

笔者在写框架jar的时候,发现一些依赖不需要在jar里面被带着引用,比如tomcat,如果使用完整的tomcat独立应用,Spring boot web就需要移除依赖。而且笔者经常需要排除其他框架jar写的很不规范的jar,经常是引入了jar本身需要依赖的其他jar,然而提供需要其他jar提供能力或者只需要引用一部分,这就是provided与optional。

scope provided

demo,以spring boot为例,假设我们使用独立的tomcat容器运行

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.4.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <version>2.2.4.RELEASE</version>
            <scope>provided</scope>
        </dependency>
           

此时,其实是独立的tomcat提供web的容器能力,spring-boot-starter-tomcat仅在编译测试时使用,并没有传递性,此功能由独立的tomcat提供。

scope

  1. compile

    ​ 没写默认就是,具有传递性,其依赖的jar也会被引用进来,随项目一直存在。

  2. provided

    上面详细讲了,没有传递性,功能由其他模块提供,常用在​ 。

  3. runtime

    ​仅会在运行和测试时,如JDBC驱动。

  4. test

    仅在测试时,用于测试test。

  5. system

    maven不会在repository拉取,而需配置特定路径。

optional

optional不是属于scope的范畴,是一个单独的标签。表示可选,即提供n种能力,也许业务只使用一种能力,由业务自行决定选择哪种依赖,必须由业务添加依赖,不然不能提供功能。

比如log,log有很多一般只需要其中一种即可,由业务根据实际来决定

<dependency>
      <groupId>ognl</groupId>
      <artifactId>ognl</artifactId>
      <version>3.2.12</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.26.0-GA</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.30</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.30</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.13.0</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.3.0</version>
      <optional>true</optional>
    </dependency>
           

mybatis亦同,mybatis支持很多数据库,然而用户就需要自行选择了,jar依赖不会传递,要使用功能必须依赖其他jar,只是这个由业务决定。

总结

provided是功能由其他应用或者模块提供,而optional是多种能力选择一种,必须手工依赖自己需要的jar,他们都没有传递性。

小技巧,笔者在deploy时,默认是不会deploy源码需要配置插件

<build>
        <plugins>
            <plugin>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <attach>true</attach>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
           

当然setting.xml需要配置上传的用户密码,必须要有deploy权限

<servers>
        <server>
            <id>快照ID</id>
            <username>xxx</username>
            <password>xxx</password>
        </server>
        <server>
            <id>正式版ID</id>
            <username>xxx</username>
            <password>xxx</password>
        </server>
    </servers>
           

需要deploy的pom需要配置,注意ID必须与上面的配置一致。

<distributionManagement>
        <repository>
            <id>正式版ID</id>
            <url>正式版url地址</url>
        </repository>
        <snapshotRepository>
            <id>快照ID</id>
            <url>快照URL</url>
        </snapshotRepository>
    </distributionManagement>
           

deploy通过版本号来区分deploy快照还是正式,比如:

1.0.0 正式版

1.0.0-snapshot 快照版