手写SpringMVC框架

/*1编写注解

编写Springmvc常用的注解

@controller

@requestmapper

@Serviceim

@autoware

通过编写如上所示的注解,来完成springmvc的基本功能

package xiao.it.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XiaoAutoware {
      String value() default "null";
}

package xiao.it.annotation;

import java.lang.annotation.Documented;
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)
@Documented
public @interface XiaoController {
   String value() default "null";
}
package xiao.it.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface XiaoRequestMapping {
    String value() default "null";
}

package xiao.it.annotation;

import java.lang.annotation.Documented;
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)
@Documented
public @interface XiaoService {
    String value() default "null";
    String param() default "null";
}

/*2 重写httpservlet的get.post方法

写一个自己的httpservelet类来完成springmvc的请求转发操作

package xiao.it.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;




public class Xiao_wornDispacherServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	
	
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		SpringmvxCore core=new SpringmvxCore();
		try {
			core.doDispacher( req, resp);
		} catch(Exception exception){
			PrintWriter writer = resp.getWriter();
			writer.write("404 请求异常");
		}
	}

    

}


/*3、包扫描

包扫描的目的
根据basepackage,就是基包(代码中指的是com),扫描下面的子包以及子包下的类
拿到包下的所有类文件后,我们就可以得到文件名
有包名有文件名,我们就可以通过反射new出这些类的实例
目的就是扫描基包下的所有的类文件,根据文件获取类的完整类名:包名+类名

通过文件的方式去扫描


4、把所有的类new出实例后,我们就要把类中的依赖关系注入进去
拿到类的Class对象
拿到field对象
拿到field上面的annotation对象
根据annotation对象拿annotation对象的属性
把属性当key拿到map中的实例
然后field。set把实例设置进去
5、建立一个url与类中方法的映射关系

其实是同样的做法
拿到类的Class对象
拿到Method对象
拿到Method上面的annotation对象

把url和method对象存到map中*/

package xiao.it.servlet;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.coyote.ActionCode;
import org.apache.tomcat.util.codec.binary.StringUtils;

import worn.it.struct.UrlMapping;
import xiao.it.annotation.XiaoAutoware;
import xiao.it.annotation.XiaoController;
import xiao.it.annotation.XiaoRequestMapping;
import xiao.it.annotation.XiaoService;



public class SpringmvxCore {

    //存放类名的文件.class
	public HashMap<String,String> nameMap=new HashMap<String, String>();
	
	//存放实例的结构  key=注解小写  value=对象
	public HashMap<String,Object> annotation=new HashMap();

	//存储URL的映射 [{url,method},{url,method}]
	public HashMap<String,UrlMapping> hashmap=new HashMap();
	
	
	public void doDispacher(HttpServletRequest req, HttpServletResponse resp) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		
		//1读取配置文件
		InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("packege.properties");
		Properties properties =new Properties();
		properties.load(resourceAsStream);
		String string = (String) properties.get("scanpackage");
	    //所描类文件
	    Scanner(string);
	    //加载类文件 
	    loadClassFile();
	    //进行spring的IoC操作
	    spring_Ioc();
	    //组织地址映射
	    handlerMapping(req,resp);
	    //最后一部 处理请求
	    parseURL(req, resp);
	}
	
	/**
	 *  处理路劲映射
	 * @param req 请求
	 * @param resp 回应
	 * @throws ClassNotFoundException 
	 */
	private void handlerMapping(HttpServletRequest req, HttpServletResponse resp) throws ClassNotFoundException {
	     
		UrlMapping urlMapping=new UrlMapping();
		
		Collection<String> values = nameMap.values();
		for(String str:values){
			
    		String classPath=str.replace(".class", "");
    		Class<?> classd = Class.forName(classPath);
    		String contextPath = req.getContextPath();
		    String baseurl=contextPath;
			    if(!classd.isInterface()){
			    	if(classd.isAnnotationPresent(XiaoController.class)){
			    		
			    		if(classd.isAnnotationPresent(XiaoRequestMapping.class)){
				    		XiaoRequestMapping annotation2 = classd.getAnnotation(XiaoRequestMapping.class);
				    		baseurl=baseurl+annotation2.value();
				    	}
				    		
				    	Method[] methods = classd.getMethods();
				    	for(Method method:methods){
				    		if(method.isAnnotationPresent(XiaoRequestMapping.class)){
				    			XiaoRequestMapping anno = method.getAnnotation(XiaoRequestMapping.class);
				    			String value = anno.value();
				    			baseurl=baseurl+value;
				    			baseurl=baseurl.replaceAll("//", "/");
				    			urlMapping.setUrl(baseurl);
				    			urlMapping.setMethod(method);
				    		}
				    	}
				    	//控制层
				      	if(classd.isAnnotationPresent(XiaoController.class)){
				      		String simpleName = classd.getSimpleName();
				      		String dealFirst = dealFirst(simpleName);
				      		Object object = annotation.get(dealFirst);
				      		urlMapping.setObj(object);
				      	}
				      	hashmap.put(urlMapping.getUrl(), urlMapping);
			    		
			    		
			    	}
		    	
			    }
		}
	}

	/**
	 * 所描包文件封装
	 * @param file
	 */
	public void Scanner(String filepath){
		String repl= filepath.replaceAll("\\*", "");
		String res= repl.replaceAll("\\.\\.", "\\.");
		String rep = res.replaceAll("\\.", "/");
		URL resource = this.getClass().getClassLoader().getResource("/"+rep);		
		String path2 = resource.getPath();
		File fi=new File(path2);
		String[] listFile = fi.list();
		//扫描所有的文件
		for(String file:listFile){
			File fle=new File(path2+file);
			if(fle.isDirectory()){
				Scanner(filepath+"."+file);
			}else{
				String name = fle.getName();
			    String classpath=res+"."+name;
				nameMap.put(name,classpath);
			}
		}
		
	}
	
	/**
	 * 加载类文件
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
    public void loadClassFile() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
    	
    	if(nameMap.size()<=0){
    		return ;
    	}
    	
    	Collection<String> values = nameMap.values();
    	for(String path:values){
    		String claname=path.replaceAll(".class", "");
    		Class<?> classd = Class.forName(claname);
    		if(!classd.isInterface()){
    			Object obj=classd.newInstance();
	    		if(classd.isAnnotationPresent(XiaoService.class)){
	    			XiaoService annotation2 = classd.getAnnotation(XiaoService.class);
	    			String key=null;
	    			String value = annotation2.value();
	    			
	    			if(!"null".equals(value)){
	    				key=value;
	    			}else{
	    				key=dealFirst(classd.getSimpleName());
	    			}
	    			annotation.put(key, obj);
	    		}else if(classd.isAnnotationPresent(XiaoController.class)){
	    			XiaoController annotation2 = classd.getAnnotation(XiaoController.class);
	    			String key=null;
	    			String value = annotation2.value();
	    			if(!"null".equals(value)){
	    				key=value;
	    			}else{
	    				key=dealFirst(classd.getSimpleName());
	    			}
	    			annotation.put(key, obj);
	    		}
    		}
    	}
    }
	
	/**
	 * 
	 * @param name  原始类名
	 * @return 首字母小写的类名
	 */
    public String dealFirst(String name){
    	String first_word = name.substring(0, 1);
    	String suString =name.substring(1);
    	String lowerCase = first_word.toLowerCase();
    	String finale=lowerCase+suString;
    	return finale;
    }
	
	/**
	 * 实例化类 并把类关系注入进去
	 * @throws ClassNotFoundException 
	 */
	public void spring_Ioc() throws ClassNotFoundException{
		try{
			Collection<Object> values = annotation.values();
			for(Object obj:values){
				Class<? extends Object> class1 = obj.getClass();
				Field[] fields = class1.getDeclaredFields();
				for(Field field:fields){
					if(field.isAnnotationPresent(XiaoAutoware.class)){
					     String name = field.getName();
					     Object object = annotation.get(name);
					     //字段中如果这个字段是私有的要对这个字段进行设置值
					     field.setAccessible(true);
					     //参数一  本对象 参数二  要注入的对象 
					     field.set(obj, object);
					}
				}	
			}
		}catch(Exception exception){
			;
		}
	}
	
	
	public void parseURL(HttpServletRequest req, HttpServletResponse resp) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		//获取请求参数
		StringBuffer requestURL = req.getRequestURL();
		String string = requestURL.toString();
		String requestURI = req.getRequestURI();
		UrlMapping urlMapping = hashmap.get(requestURI);
	
		if(null!=urlMapping){
			Object obj = urlMapping.getObj();
			Method method = urlMapping.getMethod();
			method.invoke(obj, null);
		}
	}
	
}


测试框架的使用

package worn.it.controller;

import worn.it.service.UserService;
import xiao.it.annotation.XiaoAutoware;
import xiao.it.annotation.XiaoController;
import xiao.it.annotation.XiaoRequestMapping;


@XiaoController
@XiaoRequestMapping(value="/")
public class UserController {

	@XiaoAutoware
	private UserService userService;

	@XiaoRequestMapping(value="/index")
	public String getPage(){
		userService.hello();
		return "index";
	}
	
	
}

package worn.it.service;

public interface UserService {
    void hello();
}

package worn.it.service;

import xiao.it.annotation.XiaoService;


@XiaoService(value="userService")
public class UserServiceIm implements UserService{

	@Override
	public void hello() {
		// TODO Auto-generated method stub
		System.out.println("hello spring mvc");
	}

	

}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值