在啓動App的時候,控制檯會輸出下面一行:css
Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
很好奇,GG了一下WebJars? 找到了 Roy Clarkson 在2014年寫的一篇文章《Utilizing WebJars in Spring Boot》。html
WebJars is simply taking the concept of a JAR and applying it to client-side libraries or resources. For example, the jQuery library may be packaged as a JAR and made available to your Spring MVC application. java
大概意思就是,WebJars借鑑了相似JAR的概念,把jQuery等js/css庫打包成JAR,應用在服務端,方便在SpringMVC應用中使用,官網入口。jquery
下面介紹如何使用和其原理。web
<!-- 引用Bootstrap --> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7-1</version> </dependency> <!-- 引用jQuery --> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.1.1</version> </dependency>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>WebJar Demo</title> <!-- 頁面引用WebJar --> <link rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" /> <script src="/webjars/jquery/3.1.1/jquery.min.js"></script> <script src="/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js"></script> </head> <body> <div class="container"><br/> <div class="alert alert-success"> <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a> Hello, <strong>I am using webjars!</strong> </div> </div> </body> </html>
能夠看到,index.html中的jQuery和Bootstrap資源確實被引用到了:spring
起初的猜測是,直接把js等靜態資源打包成JAR做爲Resource加入到SpringBoot中。經過看JAR包結構和源碼,發現確實是這樣作的。npm
如上圖所示,jQuery的相關文件被打包放在resources目錄下特定名字webjars下面,能夠記住這個路徑,由於後面解析引用資源的時候,就是從該路徑下訪問獲取資源的。bootstrap
WebJarsResourceResolver繼承自AbstractResourceResolver,負責解析WebJars類型的資源,下面看看這個類中作了什麼工做。bash
WebJarsResourceResolver#resolveResourceInternal,解析URL中請求的資源,返回Resource:app
private final static String WEBJARS_LOCATION = "META-INF/resources/webjars/";// webjars的位置 @Override protected Resource resolveResourceInternal(HttpServletRequest request, String requestPath, List<? extends Resource> locations, ResourceResolverChain chain) { Resource resolved = chain.resolveResource(request, requestPath, locations); if (resolved == null) {// 若是沒有解析到 String webJarResourcePath = findWebJarResourcePath(requestPath);// 尋找WebJars資源的路徑 if (webJarResourcePath != null) { return chain.resolveResource(request, webJarResourcePath, locations); } } return resolved;// 返回解析成功的資源 }
WebJarsResourceResolver#findWebJarResourcePath,找到WebJars的資源路徑:
protected String findWebJarResourcePath(String path) { int startOffset = (path.startsWith("/") ? 1 : 0); int endOffset = path.indexOf("/", 1); if (endOffset != -1) { String webjar = path.substring(startOffset, endOffset); String partialPath = path.substring(endOffset + 1); String webJarPath = webJarAssetLocator.getFullPathExact(webjar, partialPath); if (webJarPath != null) { return webJarPath.substring(WEBJARS_LOCATION_LENGTH); } } return null; }
相似這種把JavaScript/css資源打包管理不是一個新概念,在 npm 和 bower 爲web提供了類似的解決方案。
發現本身不知道的東西還有好多,慢慢學吧~