我要写框架之MVC(2)------初始化

继续上一篇的内容

本篇讲述MVC框架的初始化工作

我们可以在我们的核心控制器ActionCore里面的init方法进行初始化

之前说过我们用的是注解实现的而不是用xml,所以我们先新建一个注解

@Retention指定的是注解的声明周期,RUNTIME 意思是在运行时

@Target 表示注解定义在哪,而METHOD则代表方法

其中两个属性代表使用注解的时候的参数都是可选的 但有默认值"",使用如下

相信用过spring mvc 的人看到这里都会比较熟悉,就是当有add这个请求来到的时候会调用这个方法

而method="post" 表示只接收post请求

建好注解之后我们要进行初始化的第一步:

就是扫描所以的类,扫描来干嘛呢? 当然是扫描来映射成一个map集合

你想想我们有好多方法

@NfAction("/add")
public void add(){

}
@NfAction("/save")
public void save(){

}
@NfAction("/delete")
public void delete(){

}

我们扫描一遍,映射成map集合,就像

"/add":add()

"/save":save()

"/delete":delete()

这样当有一个add请求来的时候就很简单的获取到这个方法啦,

当然我们要记录的不止是这个方法,还有请求方式呢,

要有调用这方法要用到对象,

还有......

既然那么多东西要用到,当然就把他们封装成一个对象啦

我们就叫MyActionMapping

然后提供对应的get/set方法

说到这里,一般写框架都会用到反射,如果不会的朋友,可以先去学学

我们看到其中一个属性paras,就是代表着参数,这里会是我们遇到的第一个难题

学过反射的都知道,我们通过反射应该获取参数是Parameter,可是为什么我要自己写一个Para呢?

因为 Parameter不能获取到参数名,我们映射参数需要用到参数名,所以大家先建一个实体类

而获取参数名我们编写个Util获取需要导入javassist-3.15.0-GA.jar 这个包

具体代码如下

//获取参数名
	public static String[] getParaNames(Method m) throws NotFoundException {
		// 实例化类型池
	    ClassPool classPool = ClassPool.getDefault();
	    classPool.appendClassPath(new ClassClassPath(m.getDeclaringClass()));
	    CtClass ctClass = classPool.get(m.getDeclaringClass().getName());
	    // 获取方法
	    CtMethod method = ctClass.getDeclaredMethod(m.getName());
	    // 判断是否为静态方法
	    int staticIndex = Modifier.isStatic(method.getModifiers()) ? 0 : 1;   

	    // 获取方法的参数
	    //在得到方法后,返回代表这个方法的文件
	    MethodInfo methodInfo = method.getMethodInfo();
	    CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
	    LocalVariableAttribute localVariableAttribute = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag);
	    String[] names = new String[method.getParameterTypes().length];
	    for (int i = 0; i < method.getParameterTypes().length; i++) {
	        names[i] = localVariableAttribute.variableName(staticIndex + i);
	    }
		return names;
	}

绕了那么远,总体来说就是建立两个实体类,和获取参数名

回到我们的扫描 映射成map

我们扫描所有的class文件

public class ScanUtil {
	public List<String> scan(String url){
		List<String> list = new ArrayList<String>();
		//遍历这个文件夹下面的所有文件
		list = ergodic(url);
		//把路径换成类名
		return subString(list,url);
	}
	//递归遍历文件夹
	private List<String> ergodic(String url){
		List<String> list = new ArrayList<String>();
		File file = new File(url);
		if(file.isFile()){
			if(file.getName().matches(".*\\.class")){
				list.add(file.getAbsolutePath());
			}
		}else{
			File[] files = file.listFiles();
			for (File f : files) {
				if(f.isFile()){
					if(f.getName().matches(".*\\.class")){
						list.add(f.getAbsolutePath());
					}
				}else{
					List<String> temp = ergodic(url+File.separator+f.getName());
					for (String t : temp) {
						list.add(t);
					}
				}
			}
		}
		return list;
	}
	//截取字符串
	private List<String> subString(List<String> list,String u) {
		u = u.substring(1);
		u= u.replace("/","\\");
		List<String> paths = new ArrayList<String>();
		for (String str : list) {
			String url = str.replace(".class","");
			//换斜杠

			String newUrl = url.replace(u,"");
			String newStr = newUrl.replace("\\",".");
			paths.add(newStr);
		}
		return paths;
	}

}

扫描完然后调用一个方法annotetionMapping

通过反射生成对象获取里面的方法,属性等 封装成Maaping,判断有没有我们的注解,有就放到map集合,就那么简单

private Map<String,MyActionMapping> annotetionMapping(List<String> list){
		Map<String,MyActionMapping> map = new HashMap<String,MyActionMapping>();
		//遍历这些类
		for (String str : list) {
			Class<?> clazz = null;
			try {
				clazz = Class.forName(str);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			//获取遍历这些类的方法有没有NfAction注解
			Method[] meths = clazz.getMethods();
			for (Method method : meths) {
				NfAction myAction = method.getAnnotation(NfAction.class);
				//如果有NfAction注解
				if(myAction != null){
					String val = myAction.value();
					MyActionMapping mapping = new MyActionMapping();
					mapping.setAnnotation(myAction);
					//获取这个类
					mapping.setClazz(clazz);
					//获取这个类属性
					mapping.setFields(clazz.getFields());
					//获取这个方法
					mapping.setMethod(method);
					//获取这个方法的参数和参数名
					List<Para> paras = new ArrayList<Para>();
					String[] names = null;
					try {
						names = ParameterUtil.getParaNames(method);
					} catch (NotFoundException e) {
						e.printStackTrace();
					}
					Parameter[] ps = method.getParameters();
					for(int i=0;i<ps.length;i++){
						Para p = new Para();
						p.setName(names[i]);
						p.setPara(ps[i]);
						paras.add(p);
					}
					mapping.setParas(paras);
					map.put(val,mapping);
				}
			}
		}
		return map;
	}

最后把这个封装的结果放到我们Actioncore的成员变量里 Map<String,MyActionMapping> mappingMap;

初始化就OK啦,之后有请求来从这个map里获取就OK啦

讲的有些凌乱,不懂的话多看几遍,因为写框架本来就不是容易的事,这只是刚刚开始

我也写了几个月,下一篇,就会讲解如何处理请求和映射表单提交的参数

时间: 2024-11-09 02:11:46

我要写框架之MVC(2)------初始化的相关文章

我要写框架之MVC(1)------之前准备

开始编写框架有一段时间,现在的mvc框架基本完成,只是没有做拦截器,自定义标签那些 因为我个人比较喜欢使用注解,不喜欢用xml配置,所以一切都是注解 如果你用过MVC框架(比如:struts ,spring mvc等)都会知道他的作用 无非就是,代替servlet更加方便的进行传值,映射,调转,等 接下来的几篇,我会带大家深入了解MVC框架,有兴趣可以跟着我一起编写 首先mvc框架都会有个核心处理器,我所知道的要么是一个servlet 要么是一个过滤器 而我打算使用的是servlet  其实都差

我写的一个mvc框架讲解之一

从最原始的在jsp页面里面写代码到使用框架写代码,一路走来,大大小小的项目做了许多,接触过的mvc框架也有很多,目前开发界比较主流的mvc框架是struts2和spring mvc,都有各自缺点和优点,在项目使用过程中总有不尽人意的地方,下面主要讲解一下struts2和spring mvc在项目使用的不足之处,最终引入一个我自己写的一个mvc框架,虽然本框架还不够完善,也不敢说有多好,只是说比较合适于我的开发方式,并且已经在多个项目中使用.什么是mvc以及mvc原理,我不做讲解,自己百度 str

面向接口可扩展框架之“Mvc扩展框架及DI”

面向接口可扩展框架之“Mvc扩展框架及DI” 标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分 首先说Mvc扩展框架,该Mvc扩展就是把以前的那个Mvc分区扩展框架迁移过来,并优化整合了一下 一.Mvc扩展框架主要功能: 1.Mvc的依赖注入(DI)功能(类MvcDependency) 依赖IContainerFactory接口,不再依赖具体容器 2.Mvc全局过滤器(GlobalFilterProvider) 配置在Mvc的依赖注

Asp.net 面向接口可扩展框架之“Mvc扩展框架及DI”

标题“Mvc扩展框架及DI”有点绕口,我也想不出好的命名,因为这个内容很杂,涉及多个模块,但在日常开发又密不可分 首先说Mvc扩展框架,该Mvc扩展就是把以前的那个Mvc分区扩展框架迁移过来,并优化整合了一下 一.Mvc扩展框架主要功能: 1.Mvc的依赖注入(DI)功能(类MvcDependency) 依赖IContainerFactory接口,不再依赖具体容器 2.Mvc全局过滤器(GlobalFilterProvider) 配置在Mvc的依赖注入容器中就能自动易用上,其实逻辑很简单,就是继

Spring Boot2.0之纯手写框架

框架部分重点在于实现原理,懂原理! 废话不多说,动手干起来! SpringMVC程序入口? 没有配置文件,Spring 容器是如何加载? 回顾我们之前搭建Spring Boot项目使用的pom 引入的依赖需要parent,其作用是支持依赖 快速整合框架 不需要写版本号 还有就是web组件,自动引入springmvc spring-web spring-beans  等等都依赖进来了 SpringBoot是一个快速整合第三方框架,简化XML配置,完全采用注解.内置HTTP服务器(tomcat.je

java 使用框架Spring MVC批量上传图片

java 使用框架Spring MVC批量上传图片 运行环境:jdk1.8.0_17+tomcat 8 + spring:4.3.4+mybatis:3.2.7+ eclipse ide 2018+maven管理 最近写项目时候用到上传图片文件等功能之前写过没有总结,以及记录等,今天总结下写的批量上传图片功能 前段只需要把所有的选择的图片提交上来即可,后台会逐个处理,并且会在服务器或者当前电脑自己新建一个存放图片的文件夹,在application.properties配置里面你可以指定你所存放图

想自己写框架(1)

学了PHP也有一段时间了,从大二到现在,一直停留在某个阶段,没前进.大三用了CI 毕业时用ThinkPHP.还是觉得要自己写一个,会比较彻底. 开始看文件,再做具体分析. 按照经验来看,Common是公共文件,Conf是配置文件,Lang是语言文件,Library是核心类,Mode是数据库链接类,Tpl是模板文件 ThinkPHP.php是核心文件,应该管理统一入口. 先从ThinkPHP.php开始吧. 前面一大堆忽略了 // 加载核心Think类require CORE_PATH.'Thin

框架模式 MVC 在Android中的使用

算来学习Android开发已有2年的历史了,在这2年的学习当中,基本掌握了Android的基础知识.越到后面的学习越感觉困难,一来是自认为android没啥可学的了(自认为的,其实还有很多知识科学),二来网络上的很多框架已经帮我们做了太多的事情了,我们只需要画画UI就可以了,感觉Android开发没有太多的技术含金量.最近闲来无事,开始总结之前学过的知识点,想着是否应该学点其他的东西呢?总不能局限于Android基础知识吧.慢慢的探索发现在大的项目工程中,一个好的框架,好的设计模式,能减少很大的

【原创】Zend Framework 2框架之MVC

ZendFramework 2框架之MVC 作者:sys(360电商技术组) 1.前言 Zend Framework 2是zend官方推出的php开源框架,基于php5.3.他全然採用面向对象的代码实现,并利用了php5.3的一些新特性,比方命名空间.闭包等.由于是官方的推荐的,今天我们就来学习学习Zend Framework 2,由于本人知识浅薄,也没有实际的用Zend Framework 2做项目开发的经验.有错误的地方还请大家指正,也希望在后面的开发中能用用该框架,此篇文章权当抛砖引玉.