项目框架如上图
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中的下一个对象并赋值给resource
File 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;
}
}