項目框架如上圖
?myweb下邊三個類
package com.qcby.tomcat.myweb;import com.qcby.tomcat.webServlet.WebServlet;@WebServlet(urlPatterns = {"MyFirstServlet"})
public class MyFirstServlet {}
package com.qcby.tomcat.myweb;import com.qcby.tomcat.webServlet.WebServlet;@WebServlet(urlPatterns = {"MySecondServlet"})
public class MySecondServlet {
}
package com.qcby.tomcat.myweb;import com.qcby.tomcat.webServlet.WebServlet;@WebServlet(urlPatterns = {"MyThirdServlet"})
public class MyThirdServlet {
}
WebServlet注解
package com.qcby.tomcat.webServlet;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface WebServlet {String[] urlPatterns();
}
主方法
package com.qcby.tomcat;import com.qcby.tomcat.webServlet.WebServlet;import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;public class MyTomcat {public static void main(String[] args) {//1. 掃描包路徑 (com.qcby.tomcat.myweb)String packageName = "com.qcby.tomcat.myweb";//找到要掃描的包在哪List<Class<?>> classes = null;try {classes = getClasses(packageName);//調用這個方法獲取了myweb下邊所有類的類對象 并封裝到集合中} catch (Exception e) {e.printStackTrace();}// 2. 遍歷所有類,檢查是否有@WebServlet注解for (Class<?> clazz : classes) {if (clazz.isAnnotationPresent(WebServlet.class))//檢查是否有WebServlet類{// 3. 獲取@WebServlet注解的值WebServlet webServlet = clazz.getAnnotation(WebServlet.class);//如果 clazz 確實標記了 @WebServlet 注解,則調用 getAnnotation(Class<T> annotationClass) 方法獲取該注解實例,并將其賦予 webServlet 變量System.out.println("類名: " + clazz.getName() + " | URL路徑: " + webServlet.urlPatterns());}}}/*** 獲取指定包下的所有類** @param packageName 包名,例如 "com.qcby.tomcat.myweb"* @return 類對象列表* @throws Exception*/private static List<Class<?>> getClasses(String packageName) throws Exception {List<Class<?>> classes = new ArrayList<>();//用來封裝myweb下的三個類對象String path = packageName.replace('.', '/');// 將包名轉換為文件路徑 變成com/qcby/tomcat/myweb// 通過類加載器獲取包的資源路徑ClassLoader classLoader = Thread.currentThread().getContextClassLoader();//為了獲取當前線程的上下文類加載器 也就是獲取myweb包下的三個類文件Enumeration<URL> resources = classLoader.getResources(path);//根據指定的路徑查找所有相關資源,并將其作為 URL 集合返回 就是找到myweb下邊類的資源while (resources.hasMoreElements())//如果resources有更多的元素就進入循環{URL resource = resources.nextElement();//獲取resources中的下一個對象并賦值給resourceFile directory = new File(resource.toURI());//通過將 URL 轉換為 URI 來創建一個 File 對象。這個 File 對象表示一個目錄(或文件)// 它能夠在文件系統中表示出相應的路徑// 掃描文件夾下的所有類文件if (directory.exists())//如果這個File對象存在就進入if語句中{for (File file : directory.listFiles())//directory.listFiles()是一個File類型的數組 表示該目錄中的文件 再用fiel遍歷每個文件{if (file.getName().endsWith(".class"))//如果文件是以.class結尾則進行處理{// 獲取類的完整類名//構造類的完整類名String className = packageName + "." + file.getName().replace(".class", "");classes.add(Class.forName(className));//使用反射加載相應的類(通過類名 className)并將其添加到 classes 列表中//把符合條件的類(即帶有 @WebServlet 注解的類)加入到集合中}}}}return classes;}}