https://blog.csdn.net/txba6868/article/details/80732475
springboot在啟動的時候需要檢測當前項目是否是一個web項目,檢測方式為判斷classpath中是否有以下final變量中定義的兩個參數:
private static final String[] WEB_ENVIRONMENT_CLASSES = new String[]{"javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"};
源碼:
代碼來源:org.springframework.boot.SpringApplication.initialize(Oeject[] sources) this.webEnvironment = this.deduceWebEnvironment(); //檢測當前項目是否為web項目
代碼來源:org.springframework.boot.SpringApplication.deduceWebEnvironment()
private boolean deduceWebEnvironment() {
String[] var1 = WEB_ENVIRONMENT_CLASSES;
int var2 = var1.length;
//從全局變量中取出標識web項目的參數,遍歷
for(int var3 = 0; var3 < var2; ++var3) {
String className = var1[var3];
if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
return false;
}
}
return true;
}
代碼來源:org.springframework.util.ClassUtils.isPresent(String className,ClassLoader classLoc)
public static boolean isPresent(String className, ClassLoader classLoader) {
try {
forName(className, classLoader);
return true;
} catch (Throwable var3) {
return false;
}
}
代碼來源:org.springframework.util.ClassUtils.forName(String name,ClassLoader classLoader)
public static Class<?> forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError {
Assert.notNull(name, "Name must not be null");
//首先檢查內存中當前的className是否存在
Class<?> clazz = resolvePrimitiveClassName(name);
if (clazz == null) {
clazz = (Class)commonClassCache.get(name);
}
if (clazz != null) {
return clazz;
} else {
Class elementClass;
String elementName;
if (name.endsWith("[]")) {
elementName = name.substring(0, name.length() - "[]".length());
elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
} else if (name.startsWith("[L") && name.endsWith(";")) {
elementName = name.substring("[L".length(), name.length() - 1);
elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
} else if (name.startsWith("[")) {
elementName = name.substring("[".length());
elementClass = forName(elementName, classLoader);
return Array.newInstance(elementClass, 0).getClass();
} else {
//內存中不存在時將調用系統的classLoader從系統指定路徑進行加載
ClassLoader clToUse = classLoader;
if (classLoader == null) {
clToUse = getDefaultClassLoader();
}
//加載執行
try {
return clToUse != null ? clToUse.loadClass(name) : Class.forName(name);
} catch (ClassNotFoundException var9) {
int lastDotIndex = name.lastIndexOf(46);
if (lastDotIndex != -1) {
String innerClassName = name.substring(0, lastDotIndex) + '$' + name.substring(lastDotIndex + 1);
try {
return clToUse != null ? clToUse.loadClass(innerClassName) : Class.forName(innerClassName);
} catch (ClassNotFoundException var8) {
;
}
}
throw var9;
}
}
}
}
上述代碼提到了類加載(classLoader)。具體的類加載機制請看這里。
關於類加載的介紹,轉自: https://blog.csdn.net/briblue/article/details/54973413。
