Main.class
定义了程序启动的入口,在实际中由tomcat启动main方法
public class Main {
static {
String path = Main.class.getResource("").getPath();//获取类加载的根路径
String packageName = Main.class.getPackage().getName();//返回包名
HeaboyMvc.scanner(path,packageName);//对所有此路径下的java类进行扫描并处理
}
public static void main(String[] args) {
HeaboyMvc.exec("test","index1"); //controller+method的requestmapping
HeaboyMvc.exec("test","");
System.out.println("Hello World!");
}
}
controller示例
@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 "";
}
}
mvc工具类(模拟mvc的反射)
public class HeaboyMvc {
private static HashMap<String, Map<String,Method>> map=new HashMap<>();//存储mapping与方法对象
private static HashMap<String, Object> objMap=new HashMap<>();//存储类的对象示例,反射产生
public static void exec(String classPath,String methodPath){//执行具体方法(输入requestmapping)
if(objMap.get(classPath)==null){
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));//对方法进行invoke,使方法执行
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
public static void scanner(String path,String packageName){
List<String> paths = traverseFolder2(path);
for (String p : paths) {
p=p.substring(path.length()-1);
try {
String className=packageName+"."+p.replaceAll( Matcher.quoteReplacement(File.separator),".");
String replace = className.replace(".class", "");//至此完成对路径+类名的处理,可以调用class的方法获取类对象(Class对象)
Class<?> cl = ClassLoader.getSystemClassLoader().loadClass(replace);//通过系统类加载器加载类获得类对象
if(isController(cl)){//下面进行判断,对类上的注解进行分析处理
if(isRequestMapping(cl)){
RequestMapping requestMapping = getRequestMapping(cl);
if(map.containsKey(requestMapping.value())){
throw new RuntimeException("类多注解值:"+requestMapping.value());
}else {
map.put(requestMapping.value(),new HashMap<>());
objMap.put(requestMapping.value(),cl.newInstance());//通过反射为类创建实例对象,需要在invoke时传入此对象
}
Method[] declaredMethods = cl.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if(isRequestMapping(declaredMethod)){
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);//为类的每个方法对象都存入hash,方便调用
}
}
}
}else {
throw new RuntimeException("类无requestMapping");
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
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;
}
private static List<String> traverseFolder2(String path) {//此方法将同层级下的文件以及子文件全部扫描并返回具体的路径+文件名
File file = new File(path);
List<String> classFiles=new ArrayList<>();
if (file.exists()) {
LinkedList<File> list = new LinkedList<File>();
File[] files = file.listFiles();
for (File file2 : files) {
if (file2.isDirectory()) {
list.add(file2);
} else {
classFiles.add(file2.getAbsolutePath());
}
}
File temp_file;
while (!list.isEmpty()) {
temp_file = list.removeFirst();
files = temp_file.listFiles();
for (File file2 : files) {
if (file2.isDirectory()) {
list.add(file2);
} else {
classFiles.add(file2.getAbsolutePath());
}
}
}
} else {
}
return classFiles;
}
}
可以看到,在执行具体方法前,在main所在类中的static代码块先执行了扫描操作,将所有与main在同一路径下的类进行递归式的扫描,确认其注解是否存在以及是否合法(不可以多个mapping),将合法的存入hashmap,一个存放<类mapping,类实例>,一个存放<类mapping,<方法mapping,method对象>,这样可以在调用时很快的找到方法,如不存在则提示报错(访问不到)。