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
-
compile
沒寫預設就是,具有傳遞性,其依賴的jar也會被引用進來,随項目一直存在。
-
provided
上面詳細講了,沒有傳遞性,功能由其他子產品提供,常用在 。
-
runtime
僅會在運作和測試時,如JDBC驅動。
-
test
僅在測試時,用于測試test。
-
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 快照版