1.Annocatioon
@Target(ElementType.xxxx)
@Retention(RetentionPolicy.xxxx)
public @interface 注解名 {
}
Target:
对应的是当前的注解能够定义在哪个位置上。
ElementType.Type -- 类
ElementType.Field --
字段
ElementType.Method --
方法
Retention:
在什么场景下能够起作用。
RetentionPolicy.CLASS -
定义类
RetentionPolicy.RUNTIME --
运行时
@Controller
package com.csi.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}
@RequestMapping
package com.csi.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
String value() default "" ;
}
2.解析Annotation
扫描包的工具类
package com.csi.utils;
import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
/**
* 找到某个包下的所有的以.class结尾的java文件
*/
public class ClassScanner {
/**
* 获得包下面的所有的class
* @param
* @return List包含所有class的实例
*/
public static List<Class<?>> getClasssFromPackage(String packageName) {
List<Class<?>> clazzs = new ArrayList<>();
// 是否循环搜索子包
boolean recursive = true;
// 包名对应的路径名称
String packageDirName = packageName.replace('.', '/');
Enumeration<URL> dirs;
try {
//从当前正在运行的线程中,加载类加载器,通过给定的包名,找到所有该包下的类
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
while (dirs.hasMoreElements()) {
URL url = dirs.nextElement();
String protocol = url.getProtocol();
if ("file".equals(protocol)) {
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
findClassInPackageByFile(packageName, filePath, recursive, clazzs);
}
}
} catch (Exception e) {
e.printstacktrace();
}
return clazzs;
}
/**
* 在package对应的路径下找到所有的class
*/
public static void findClassInPackageByFile(String packageName, String filePath, final boolean recursive,
List<Class<?>> clazzs) {
File dir = new File(filePath);
if (!dir.exists() || !dir.isDirectory()) {
return;
}
// 在给定的目录下找到所有的文件,并且进行条件过滤
File[] dirFiles = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
boolean acceptDir = recursive && file.isDirectory();// 接受dir目录
boolean acceptClass = file.getName().endsWith("class");// 接受class文件
return acceptDir || acceptClass;
}
});
for (File file : dirFiles) {
if (file.isDirectory()) {
findClassInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, clazzs);
} else {
String className = file.getName().substring(0, file.getName().length() - 6);
try {
clazzs.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + "." + className));
} catch (Exception e) {
e.printstacktrace();
}
}
}
}
}
监听器:ClassLoaderContextListener
package com.csi.listener;
import com.csi.annotation.Controller;
import com.csi.annotation.RequestMapping;
import com.csi.utils.ClassScanner;
import javax.servlet.ServletContextEvent;
import javax.servlet.servletcontextlistener;
import java.lang.reflect.Method;
import java.util.List;
public class ClassLoaderContextListener implements servletcontextlistener {
@Override
public void contextinitialized(ServletContextEvent sce) {
initClassLoader();
}
private void initClassLoader() {
//根据包找到包下面所有的类
List<Class<?>> classList = ClassScanner.getClasssFromPackage("com.csi.controller");
//遍历所有的类
for (Class<?> clazz : classList) {
//如果当前类上存在Controller,就要获取方法
if (clazz.isAnnotationPresent(Controller.class)) {
//获得方法得名称
Method[] methods = clazz.getmethods();
//遍历当前包含了Controller注解得所有方法
for (Method method : methods) {
//判断方法上是否添加了RequestMapping注解
if (method.isAnnotationPresent(RequestMapping.class)) {
//获取到包含了RequestMapping注解的value值
String urlPath = method.getAnnotation(RequestMapping.class).value();
//将值作为键,将方法作为值,存储在map集合中
WebApplicationContext.methodMap.put(urlPath, method);
}
}
}
}
}
}
解析用户的请求路径:
package com.csi.servlet;
import com.csi.listener.WebApplicationContext;
import javax.servlet.servletexception;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class dispatcherServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws servletexception, IOException {
//步骤1:获取到用户的请求URL
String urlPath = req.getServletPath();
Method method = WebApplicationContext.methodMap.get(urlPath);
if (method != null) {
//步骤2:调用对应的Method方法
//2-1:如何找到要对应的类
Object instance = null;
try {
instance = method.getDeclaringClass().newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (illegalaccessexception e) {
throw new RuntimeException(e);
}
try {
method.invoke(instance, req, resp);
} catch (illegalaccessexception e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
} else {
resp.sendRedirect("failure.jsp");
}
}
}
3.使用
3.1:需要在工程下建立com.csi.controller的包
3.2:在包中建立类,在该类上,添加@Controller的注解
3.3:建立类中的方法,根据需求,在适当的方法上添加@RequestMapping的注解.
4.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.csi</groupId>
<artifactId>shop</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.csi</groupId>
<artifactId>MyMvcFrameWork</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/MysqL/mysql-connector-java -->
<dependency>
<groupId>MysqL</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8888</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
原文地址:https://www.jb51.cc/wenti/3287952.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。