1.创建简单的注解
1.1 Controller
package com.heaboy.annotation;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @ interface Controller {
}
1.2 RequestMapping
package com.heaboy.annotation;
import java.lang.annotation.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface RequestMapping {
String value() default "";
}
2.创建controller类
package com.heaboy.controller;
import com.heaboy.annotation.Controller;
import com.heaboy.annotation.RequestMapping;
@Controller
@RequestMapping("test")
public class TestController {
@RequestMapping
public String index(){
System.out.println("test->index");
return "";
}
@RequestMapping("index1")
public String index1(){
System.out.println("test->index1");
return "";
}
}
package com.heaboy;
import com.heaboy.annotation.Controller;
import com.heaboy.annotation.RequestMapping;
@Controller
@RequestMapping
public class IndexController {
@RequestMapping
public void index(){
System.out.println("index -> index");
}
}
3.SpingMVC实现类
package com.heaboy.mvc;
import com.heaboy.Main;
import com.heaboy.annotation.Controller;
import com.heaboy.annotation.RequestMapping;
import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.channels.ClosedSelectorException;
import java.sql.SQLOutput;
import java.util.*;
import java.util.regex.Matcher;
public class HeaboyMvc {
private static HashMap<String, Map<String,Method>> map=new HashMap<>();
private static HashMap<String,Object> objMap=new HashMap<>();
public static void scanner(String path,String packageName) {
//扫描main所在包中的类以及子包中的类的绝对路径
List<String> paths=traverseFolder2(path);
for (String p : paths) {
p=p.substring(path.length()-1);
//遍历每一个类文件的绝对路径,并且处理只剩下对main的相对路径
try {
String className=packageName+"."+p.replaceAll(Matcher.quoteReplacement(File.separator),".");
//包名加相对路径,把相对路径的/换成.
String replace=className.replace(".class","");
//去掉.class后缀
Class<?> cl=Class.forName(replace);
//获取改类的class对象
if (isController(cl)){
//是否有controller注解
if (isRequestMapping(cl)){
//是否有requestMapping注解
RequestMapping requestMapping=getRequestMapping(cl);
//获取requestmapping注解
if (map.containsKey(requestMapping.value())){
throw new RuntimeException("类多注解值:"+requestMapping.value());
//跟之前扫描的名字冲突报错
}else {
map.put(requestMapping.value(),new HashMap<>());
//类的requestMapping注解值和map字典放入字典中
objMap.put(requestMapping.value(),cl.newInstance());
//类的注解值和类对象放入字典中
}
Method[] declaredMethods=cl.getDeclaredMethods();
//获取该对象的每一个方法对象
for (Method declaredMethod : declaredMethods) {
//遍历方法对象
if (isRequestMapping(declaredMethod)){
//判断该方法是否有requesting注解
RequestMapping mapping=getRequestMapping(declaredMethod);
//获取该方法的注解
if (map.get(requestMapping.value()).containsKey(mapping.value())){
//判断该类是否有相同的注解值,有就报错
throw new RuntimeException("方法多注解值:"+requestMapping.value());
}else {
map.get(requestMapping.value()).put(mapping.value(),declaredMethod);
//没有就添加map对应类的方法字典中
}
}
}
}else {
throw new RuntimeException("类无requestMapping");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public static void exec(String classPath,String methodPath){
if (objMap.get(classPath)==null){
//判断objmap字典中是否有这个类,没有则报错
System.out.println("没有这个类 404");
}else{
if (map.get(classPath).get(methodPath)==null){
//判断该类中是否有该方法
System.out.println("没有这个方法 404");
}else {
try {
//获取该类的该方法并且执行
map.get(classPath).get(methodPath).invoke(objMap.get(classPath));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
}
private static List<String> traverseFolder2(String path){
//创建main所在文件夹对象
File file=new File(path);
ArrayList<String> classPaths=new ArrayList<>();
//创建数组,存放类路径
if (file.exists()){
//文件夹存在执行
LinkedList<File> list=new LinkedList<>();
//存放子文件夹路径以及子子文件夹数量
File[] files=file.listFiles();
//把main所在文件夹下的子文件夹和文件放入数组
for (File file1 : files) {
//遍历
if (file1.isDirectory()){
//判断是不是文件夹
list.add(file1);
//是放入子文件夹集合
}else {
classPaths.add(file1.getAbsolutePath());
//文件则放入文件集合
}
}
while (!list.isEmpty()){
//子文件夹集合不为空,一直遍历,直到空为止
File directory=list.removeFirst();
//弹出第一个子文件夹对象
File[] files1=directory.listFiles();
for (File file1 : files1) {
if (file1.isDirectory()){
list.add(file1);
//判断是否为文件夹,是则放入集合
}else {
classPaths.add(file1.getAbsolutePath());
//文件则放入类集合
}
}
}
}
return classPaths;
}
private static boolean isController(Class cl){
Annotation annotation=cl.getAnnotation(Controller.class);
if (annotation!=null){
return true;
}
return false;
}
private static boolean isRequestMapping(Class cl){
Annotation annotation=cl.getAnnotation(RequestMapping.class);
if (annotation!=null){
return true;
}
return false;
}
private static boolean isRequestMapping(Method method){
Annotation annotation=method.getAnnotation(RequestMapping.class);
if (annotation!=null){
return true;
}
return false;
}
private static RequestMapping getRequestMapping(Class cl){
Annotation annotation=cl.getAnnotation(RequestMapping.class);
if (annotation instanceof RequestMapping){
return (RequestMapping) annotation;
}
return null;
}
private static RequestMapping getRequestMapping(Method method){
Annotation annotation = method.getAnnotation(RequestMapping.class);
if(annotation instanceof RequestMapping){
return (RequestMapping) annotation;
}
return null;
}
}
4.启动类
package com.heaboy;
import com.heaboy.mvc.HeaboyMvc;
import java.util.Stack;
public class Main {
static {
String path=Main.class.getResource("").getPath();
//获取main方法的路径
String packageName=Main.class.getPackage().getName();
//获取main方法所在包的路径
HeaboyMvc.scanner(path,packageName);
//扫描main所在包中的类以及子包中的类
}
public static void main(String[] args) {
HeaboyMvc.exec("","");
HeaboyMvc.exec("test","index1");
HeaboyMvc.exec("test","");
HeaboyMvc.exec("test","asdfasdfasdf");
HeaboyMvc.exec("test","");
}
}
5.结果展示