[英]Embedded Tomcat with Servlet 3.0 - How to skip certain jars when scanning?
這是嵌入式Tomcat服務器掃描Servlet 3.0初始化程序的簡單方法:
public static void main(String[] args) throws ServletException, LifecycleException {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File("web").getAbsolutePath());
//declare an alternate location for your "WEB-INF/classes" dir:
File additionWebInfClasses = new File("target/classes");
VirtualDirContext resources = new VirtualDirContext();
resources.setExtraResourcePaths("/WEB-INF/classes=" + additionWebInfClasses);
ctx.setResources(resources);
tomcat.start();
System.out.println("Started");
tomcat.getServer().await();
}
我知道catalina.properties
中的屬性tomcat.util.scan.DefaultJarScanner.jarsToSkip
允許您限制掃描哪些jar來加快部署時間。 我如何將相同的想法整合到嵌入式Tomcat代碼中?
獎勵:有沒有一種方法可以指定要包括的jar而不是要跳過的 jar?
盡管我沒有特定的方式來加載單個catalina.properties
屬性,但我發現它足以方便地在Tomcat容器上下文中重載JarScanner本身,如下所示:
答案在Groovy中 (對不起,我很懶)
public static void main(String[] args) throws ServletException, LifecycleException {
Tomcat tomcat = new TomcatWithFastJarScanner()
tomcat.setPort(8080)
StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File("web").getAbsolutePath())
//declare an alternate location for your "WEB-INF/classes" dir:
VirtualDirContext resources = new VirtualDirContext()
resources.setExtraResourcePaths("/WEB-INF/classes=" + new File("target/classes"))
ctx.setResources(resources)
tomcat.start()
println "Started server on port 8080"
tomcat.getServer().await()
}
private static class TomcatWithFastJarScanner extends Tomcat {
@Override
public void start() throws LifecycleException {
getServer().findServices().each { service ->
service.getContainer().findChildren().each { container ->
container.findChildren().each { c ->
((Context) c).setJarScanner(new FastJarScanner())
}
}
}
super.start()
}
}
private static class FastJarScanner extends StandardJarScanner {
def jarsToInclude = [ 'spring-web.*' ]
@Override
public void scan(ServletContext context, ClassLoader classloader,
JarScannerCallback callback, Set<String> jarsToSkip) {
jarsToSkip = new HashSet<String>();
((URLClassLoader) classloader.getParent()).getURLs().each {
def jar = it.path.find(/[^\/]+\.jar$/)
if(!jar) return
for(String inclusionPattern : jarsToInclude) {
if(jar.find(inclusionPattern))
println "including jar: " + jar
else jarsToSkip.add(jar)
}
}
super.scan(context, classloader, callback, jarsToSkip);
}
}
基本思想是,我們正在查看類加載器可以看到的所有jar,並排除了我們不想包含的所有jar。
Tomcat嵌入式可以像這樣快速啟動!
以下是推測性內容,僅閱讀規格。 可以使用網絡片段,並使用自己的META-INF / web.xml,其中metadata-complete = true表示無注釋掃描。
您可以將Tomcat設置scanClassPath擴展為false,類似-這是在此處用戶jkschneider指出的之上 ):
new Tomcat() {
@Override
public void start() throws LifecycleException {
for (final org.apache.catalina.Service service : getServer().findServices()) {
for (final Container container : service.getContainer().findChildren()) {
for (final Container subContainer : container.findChildren()) {
final StandardJarScanner jarScanner = (StandardJarScanner) ((Context) subContainer).getJarScanner();
jarScanner.setScanClassPath(false);
}
}
}
super.start();
}
};
更好的方法可能如下:
final Tomcat tomcat = new Tomcat();
final StandardHost tomcatHost = (StandardHost) tomcat.getHost();
tomcatHost.setContextClass("com.fullclassname....FastStandardContext");
FastStandardContext
在哪里
public class FastStandardContext extends StandardContext {
public FastStandardContext() {
((StandardJarScanner) getJarScanner()).setScanClassPath(false);
}
}
這將涵蓋在tomcat運行后添加新的Web應用程序的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.