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 快照版