Spring Boot 的自动装配使用的是 spring-boot-starter
这种方式,spring-boot-starter
分成很多的模块,比如 web 模块,在没有引入 spring-boot-starter-web
的时候,自动装配的很多类都是报红的:
同样地,在 PageHelper 中 CacheFactory
也这么用过:
public abstract class CacheFactory {
/**
* 创建 SQL 缓存
*
* @param sqlCacheClass
* @return
*/
public static <K, V> Cache<K, V> createCache(String sqlCacheClass, String prefix, Properties properties) {
if (StringUtil.isEmpty(sqlCacheClass)) {
try {
Class.forName("com.google.common.cache.Cache");
return new GuavaCache<K, V>(properties, prefix);
} catch (Throwable t) {
return new SimpleCache<K, V>(properties, prefix);
}
} else {
...
}
}
}
如果引用了 Guava 就会使用 Guava 中的 Cache
。我现在的项目中并未引用 Guava,所以 GuavaCache
也会报红:
其实原因很简单,就是 Maven 的可选依赖配置,可以参看 PageHelper
中的依赖情况:
<!--
可选依赖:guava
当项目包含guava时,会使用 GuavaCache,详情看4.2.0更新日志
-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
再看 spring-boot-autocionfigure 中的部分依赖情况:
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
<version>2.0.30.Final</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
<version>2.0.30.Final</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
Maven 可选依赖
以上文的内容为例,我的工程与 PageHelper 的依赖关系为:
可选依赖
myProject
PageHelper
Guava
一般情况下,在默认的 scope(compile)下,myProject 会依赖于 Guava,但是由于是可选依赖,Guava 是不会被传递到 myProject 的,如果 myProject 需要使用 Guava,则需要显示的依赖 Guava,其实这样也是一种插拔式的设计(与 Maven 的多 profile 要区开)。在 《Maven 实战中》也有提到相关的设计思想:
在理想的情况下,是不应该使用可选依赖的。前面我们可以看到, 使用可选依赖的原因是某一个项目实现了多个特性, 在面向对象设 中,有个单一职责性原则,意指一个类应该只有一项职责,而不是糅合太多的功能。这个 原则在规划 Maven 项目的时候也同样适用,在上面的例子中,更好的做法是为 MySQL 和 PostgreSQL 分别创建一个 Maven 项目, 基于同样的 groupId 分配不同的 artifactId,如 com.juvenxu.mvnbook:project-b-mysql 和 com.juvenxu.mvnbook:project-b-postgresql, 在各自的 POM 中声明对应的 JDBC 驱动依赖,而且不使用可选依赖,用户则根据需要选择使用 project-b-mysql 或者 project-b-postgresql,由于传递性依赖的作用,就不用再声明 JDBC 驱 动依赖。
References
- 《Maven 实战》