声明:
本文实现SpringMVC基本功能,注释加在代码里面,本文最后有gitee上源码地址
Main
public class Main {
//类一加载就执行这个静态块
static {
//当前类所在的路径
String path = Main.class.getResource("").getPath();
//当前类所在的包名
String packageName = Main.class.getPackage().getName();
HeaboyMvc.scanner(path,packageName);
}
public static void main(String[] args) {
HeaboyMvc.exec("","");
HeaboyMvc.exec("test","index1");
HeaboyMvc.exec("test","");
System.out.println("Hello World!");
}
}
- 我们执行程序从这个类开始,类加载的时候,先执行静态块(扫描所有的文件,把类文件的实例和类文件的方法 用HashMap存起来)
- main方法中的exec是模拟调用接口,第一个参数是类的@RequestMapping的value值,第二个参数是方法的@ReqeustMapping的value值
HeaboyMvc
public class HeaboyMvc {
//存类的方法
private static HashMap<String, Map<String,Method>> map=new HashMap<>();
//存类的实例
private static HashMap<String, Object> objMap=new HashMap<>();
public static void exec(String classPath,String methodPath){
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));
} 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<?> cl = ClassLoader.getSystemClassLoader().loadClass(replace);
//判断是否为Controller
if(isController(cl)){
//判断是否加RequestMapping
if(isRequestMapping(cl)){
//拿到注解
RequestMapping requestMapping = getRequestMapping(cl);
//判断注解中的值是否重复
if(map.containsKey(requestMapping.value())){
throw new RuntimeException("类多注解值:"+requestMapping.value());
}else {
//没有重复就把类放两个map进去
map.put(requestMapping.value(),new HashMap<>());
objMap.put(requestMapping.value(),cl.newInstance());
}
//拿到类中的方法
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);
}
}
}
}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()) {
//新建list用来存放文件
LinkedList<File> list = new LinkedList<File>();
File[] files = file.listFiles();
//遍历
for (File file2 : files) {
//只要是文件夹就添加进list
if (file2.isDirectory()) {
list.add(file2);
} else {
//不是文件夹就放到classFiles中
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;
}
}
- 先扫包,如果是文件夹就放到list中,如果不是文件夹就是文件就放到classFiles中,判断list是否为空,如果不为空就把存进的文件夹的文件展示出来继续遍历,同时把此文件夹从list中取出,经过几次之后,就可以获得所有得到类文件的路径
- 遍历classFiles,拿到包名,对遍历出的类文件的路径进行替换和截取,获得了类的全限定名,判断加没加@Controller注解,再判断加没加@RequestMapping注解,判断@RequeatMapping注解中的value是否重复,如果不重复就把此value存起来,并对此类中的方法进行遍历,如果方法加了@RequestMapping,就用map把方法的value也存起来
注解
Controller
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @ interface Controller {
}
RequestMapping
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface RequestMapping {
/**
*
* @return
*/
String value() default "";
}
TestController
@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 "";
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80096.html