SpringMVC 包扫描+ C的模拟

今天在回顾代理模式时,发现了一些问题,联想到annotation,结合springMVC以往的使用经历,就写了下面这写代码。

       1. 简单实现spring包扫描

       2. 对之前代理模式,做了下修改,可以对比 ActionProxy 类的实现。(之前把代理模式概念和jdk自带InvocationHandler胡拼乱凑,错误结合。) 

      知识点:  java 类加载器, java反射相关API,代理,annotation,一个内部内实现的单例,代理模式和工厂模式结合。就这些小知识点。


代码结构:


代码介绍:

代码介绍:
action类:
     UserAction.java  用户管理的相关C
annotation(自定义注解):
     UAction :控制类标记
     UParamAttr: 方法参数绑定注解
     URequestMapper: 请求URL路径注解
mapper(用来存储注解配置):
     ActionMapper
proxy(代理和代理工厂类):
     ActionProxy.java
     ActionProxyFactory.java
scan(注解扫描):
     Scan.java
service:
     DB.java  假的service
servlet:假的dispatchServlet
     Servlet.java
vo(实体对象):
     ActionMapperVo.java  方法映射
     ParamMapper.java     方法参数映射
     URequest.java         请求实体,假HttpServletRequest
     User.java             用户实体
 TestMain.java  测试类

详细代码:

扫描二维码关注公众号,回复: 3027488 查看本文章
UserAction.java  用户管理的相关C:
package com.bo.example.action;

import java.util.List;

import com.bo.example.annotation.UAction;
import com.bo.example.annotation.UParamAttr;
import com.bo.example.annotation.URequestMapper;
import com.bo.example.service.DB;
import com.bo.example.vo.User;

@UAction
@URequestMapper("/user")
public class UserAction  {
	 @URequestMapper("/list")
	  public List<User> list(){
		  return DB.queryUserList();
	  }
	 @URequestMapper("/add")
	 public Object addUser(@UParamAttr("userinfo") User u){
		 return DB.addUser(u);
	 }
	 @URequestMapper("/remove")
	 public Object removeUser(@UParamAttr("userinfo") User u){
		 return DB.removeUser(u);
	 }
}


annotation(自定义注解):
     UAction :控制类标记
	package com.bo.example.annotation;

	import java.lang.annotation.ElementType;
	import java.lang.annotation.Retention;
	import java.lang.annotation.RetentionPolicy;
	import java.lang.annotation.Target;
	/*
	 * @Target 说明了Annotation所修饰的对象范围:
	 * 	Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、
	 * 			类型成员(方法、构造方法、成员变量、枚举值)、
	 *          方法参数和本地变量(如循环变量、catch参数)。
	 *       	在Annotation类型的声明中使用了target可更加明晰其修饰的目标
	 *       
	 *  @Retention定义了该Annotation被保留的时间长短:
	 *  				某些Annotation仅出现在源代码中,而被编译器丢弃;
	 *  				而另一些却被编译在class文件中;
	 *  				编译在class文件中的Annotation可能会被虚拟机忽略,
	 *  				而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。
	 *  				使用这个meta-Annotation可以对 Annotation的“生命周期”限制。     
	 */
	@Retention(value=RetentionPolicy.RUNTIME)
	@Target(value=ElementType.TYPE)
	/**
	 * action标记
	 * @author 波
	 *
	 */
	public @interface UAction { 
		public String value() default ""; 
	}

      UParamAttr: 方法参数绑定注解
	package com.bo.example.annotation;

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

	/**
	 * 参数绑定注解
	 * @author 波
	 *
	 */
	@Retention(value=RetentionPolicy.RUNTIME)
	@Target(value=ElementType.PARAMETER)
	public @interface UParamAttr {
		public String value() default ""; 
	}
     URequestMapper: 请求URL路径注解
	package com.bo.example.annotation;

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

	/**
	 * 请求路径注解
	 * @author 波
	 *
	 */
	@Retention(value=RetentionPolicy.RUNTIME)
	@Target(value={ElementType.METHOD,ElementType.TYPE})
	public @interface URequestMapper {
		String value() default "";
	}

mapper(用来存储注解配置): ActionMapper
package com.bo.example.mapper;

import java.util.Hashtable;

import com.bo.example.vo.ActionMapperVo;
/**
 * 单例模式
 * @author 波
 *
 */
public class ActionMapper {
	private ActionMapper(){}
	
	static class ActionMapperFactory{
		private static final ActionMapper mapper = new ActionMapper();
	}
	public static final ActionMapper instance = ActionMapperFactory.mapper;
	private Hashtable<String,ActionMapperVo> hashtable = new Hashtable<>();
	
	public void put(String key,ActionMapperVo vo){
		this.hashtable.put(key, vo);
	}
	
	public ActionMapperVo get(String key){
		return this.hashtable.get(key);
	}
}

proxy(代理和代理工厂类): ActionProxy.java
package com.bo.example.proxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * 代理模式
 * @author 波
 *
 */
public class ActionProxy {
		private Object obj;

		public ActionProxy(Object obj) {
			super();
			this.obj = obj;
		}
		
		public Object execute(Method method,Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
			before();
			Object obj= method.invoke(this.obj, args);
			after();
			return obj;
		}
		
		public void before(){
			System.out.println("before ----");
		}
		
		public void after(){
			System.out.println("after----");
		}
}

proxy(代理和代理工厂类): ActionProxyFactory.java
package com.bo.example.proxy;
/**
 * 工厂模式
 * @author 波
 *
 */
public class ActionProxyFactory {
	public static ActionProxy getProxy(Class<?> cls) throws InstantiationException, IllegalAccessException{
		 return new ActionProxy(cls.newInstance());
	}
}

scan(注解扫描): Scan.java
package com.bo.example.scan;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.bo.example.annotation.UAction;
import com.bo.example.annotation.UParamAttr;
import com.bo.example.annotation.URequestMapper;
import com.bo.example.mapper.ActionMapper;
import com.bo.example.vo.ActionMapperVo;
import com.bo.example.vo.ParamMapper;
import com.bo.util.Constant;
/**
 * 实现包扫描
 * @author 波
 *
 */
public class Scan {
	//要扫描的包路径
	private static String scan_package_path = null;
	private static String classloader_rootpath =null;//当前类加载器加载的文件路径
	private static ClassLoader loader = null;//类加载器
	private static String class_file_path=null;//class文件路径
	static {
		Scan.scan_package_path="com.bo.example.action";//可以从配置文件读取。
		loader = ClassLoader.getSystemClassLoader();//获得当前系统类加载器。
		Scan.classloader_rootpath = Scan.loader.getResource(Constant.POINT).getFile();//
		Scan.class_file_path =loader.getResource("./com/bo/example/action/").getFile();
	}
	/**
	 * 扫描指定路径下的类,并将注解配置放入内存。
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public void scan() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		System.out.println("扫描开始---");
		List<Class<?>> lst = new ArrayList<>();
		File directory = new File(Scan.class_file_path);
		if(directory.exists()){
			String _rootPath = Scan.classloader_rootpath.replaceAll(Constant.SPECIAL_BIAS_LINE_0, Constant.POINT)
					 .replaceAll(Constant.SPECIAL_BIAS_LINE_1, Constant.POINT);
			this.listDirectory(_rootPath, directory, lst);
			
			for (Class<?> cls : lst) {
				this.initActionMapper(cls);
			}
		}
		System.out.println("扫描结束---");
	}
	/**
	 *    递归获取目录下所有.class文件
	 * @throws ClassNotFoundException 
	 */
	private void listDirectory(String rootPath,File directory,List<Class<?>> lst) throws ClassNotFoundException{
			if(!directory.isDirectory()) return;
			if(!directory.exists()) return;
			if(!directory.canRead()) return;
			
			File[]	fileList  = directory.listFiles();
			for (File file : fileList) {
				 if(!file.isDirectory()){
					 String filePath = file.getPath().replaceAll(Constant.SPECIAL_BIAS_LINE_0, Constant.POINT)
							 .replaceAll(Constant.SPECIAL_BIAS_LINE_1, Constant.POINT);
					 String classPath = filePath.replace(rootPath.substring(1, rootPath.length()),"");
					 Class<?> cls = Scan.loader.loadClass(classPath.substring(0, classPath.length()-6));
					 lst.add(cls);
				 }else{
					 this.listDirectory(rootPath, file, lst);
				 }
			}
	}
	
	private void initActionMapper(Class<?> cls) throws InstantiationException, IllegalAccessException{
			//获取Action类标记注解
		   UAction uAction = cls.getAnnotation(UAction.class);
		   if(uAction!=null){
			     //获取类的URequestMapper注解(功能域 例如:用户管理控制类/user)
			    URequestMapper uRequestMapper = cls.getAnnotation(URequestMapper.class);
			    String requestDomainUrl = "";
			    if(uRequestMapper!=null){
			    	requestDomainUrl = uRequestMapper.value();
			    }
			    //获取所有的方法
			    Method[] methodList=cls.getMethods();
			    for (Method method : methodList) {
			    	//获取method方法的注解
			    	URequestMapper mURequestMapper = method.getAnnotation(URequestMapper.class);
			    	if(mURequestMapper == null) continue;
			    	//方法请求路径 例如: /add 等
			    	String mURequestUrl = mURequestMapper.value();
			    	//获取参数列表
			    	Class<?>[] parameterTypes = method.getParameterTypes();
			    	//参数列表
			    	ParamMapper[] paramArray =null;
			    	if(parameterTypes.length>0){
			    		paramArray = new ParamMapper[parameterTypes.length];
				    	//获取方法参数注解
				    	Annotation[][] parameterAnnotationArray = method.getParameterAnnotations();
				    	int param_type_index = 0;
				    	for (Annotation[] annotations : parameterAnnotationArray) {
				    		ParamMapper paramMapper = new ParamMapper();
				    		paramMapper.setParamType(parameterTypes[param_type_index]);
				    		for (Annotation annotation : annotations) {
								if(annotation instanceof UParamAttr){
									UParamAttr uParamAttr = (UParamAttr)annotation;
									paramMapper.setMapper(true);
									paramMapper.setParamKey(uParamAttr.value());
								}
							}
				    		paramArray[param_type_index] = paramMapper;
				    		param_type_index++;
						}
			    	}
			    	ActionMapperVo vo  = new ActionMapperVo();
		    		vo.setCls(cls);
		    		vo.setArgs(paramArray);
		    		vo.setMethod(method);
		    		vo.setRequestMapperUrl(requestDomainUrl+mURequestUrl);
		    		ActionMapper.instance.put(requestDomainUrl+mURequestUrl, vo);
				}
		   }
			
	}
}

service: DB.java  假的service
package com.bo.example.service;

import java.util.ArrayList;
import java.util.List;

import com.bo.example.vo.User;

public class DB {
	private static List<User> userList = new ArrayList<>();
			
	static{
		userList = (userList!=null? userList:new ArrayList<User>());
		for(int i=0;i<5;i++){
			User u = new User();
			u.setUid("uid00"+i);
			u.setUname("uname00"+i);
			userList.add(u);
		}
	}	
	
	public static List<User> queryUserList(){
		return DB.userList;
	}
	
	public static boolean removeUser(User u){
		return DB.userList.remove(u);
	}
	
	public static boolean addUser(User u){
		return DB.userList.add(u);
	}
}

servlet:假的dispatchServlet  Servlet.java
package com.bo.example.servlet;

import java.util.Map;

import com.bo.example.mapper.ActionMapper;
import com.bo.example.proxy.ActionProxy;
import com.bo.example.scan.Scan;
import com.bo.example.vo.ActionMapperVo;
import com.bo.example.vo.ParamMapper;
import com.bo.example.vo.URequest;
/**
 * 简单是个意思,别太介意。哈哈 ,类似:dispatchServlet假的。
 * @author 波
 *
 */
public class Servlet {
	public Servlet(){
		init();
	}
	public void init(){
		//包扫描-----Spring启动初始化
		Scan scan = new Scan();
		try {
			scan.scan();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public Object doPost(URequest request) throws Exception{
		String path = request.getPath();
		Object result = null; 
		Map<String,Object> requestParam =  request.getRequestParam();
		ActionMapperVo vo = ActionMapper.instance.get(path);
		if(vo!=null){
			ActionProxy proxy = (ActionProxy) com.bo.example.proxy.ActionProxyFactory.getProxy(vo.getCls());
			Object[] args = null;
			ParamMapper[] paramArray=	vo.getArgs();
			if(paramArray!=null){
				int args_index = 0;
				args = new Object[paramArray.length];
				for (ParamMapper paramMapper : paramArray) {
						if(paramMapper.isMapper()){
							args[args_index] = requestParam.get(paramMapper.getParamKey());
						}else{
							Object _obj = paramMapper.getParamType().newInstance();
							if(_obj instanceof URequest){
								args[args_index] =  request;
							}else{
								args[args_index] = _obj;
							}
							
						}
						args_index++;
				}
			}
			result = proxy.execute(vo.getMethod(), args);
		}else{
			System.out.println("没有找到处理类");
		}
		return result;
	}
}

vo(实体对象):  ActionMapperVo.java  方法映射
package com.bo.example.vo;

import java.lang.reflect.Method;

public class ActionMapperVo {
	private Class<?> cls; //类描述
	private String requestMapperUrl;//请求路径
	private Method method;//映射的方法
	private ParamMapper[] args;//方法参数列表
	public Class<?> getCls() {
		return cls;
	}
	public void setCls(Class<?> cls) {
		this.cls = cls;
	}
	public String getRequestMapperUrl() {
		return requestMapperUrl;
	}
	public void setRequestMapperUrl(String requestMapperUrl) {
		this.requestMapperUrl = requestMapperUrl;
	}
	public Method getMethod() {
		return method;
	}
	public void setMethod(Method method) {
		this.method = method;
	}
	public ParamMapper[] getArgs() {
		return args;
	}
	public void setArgs(ParamMapper[] args) {
		this.args = args;
	}
}

vo(实体对象):  ParamMapper.java     方法参数映射
package com.bo.example.vo;

public class ParamMapper {
	private Class<?> paramType;
	private String paramKey;
	private boolean isMapper;
	
	public ParamMapper() {
		// TODO Auto-generated constructor stub
		this.isMapper = false;
	}

	public Class<?> getParamType() {
		return paramType;
	}

	public void setParamType(Class<?> paramType) {
		this.paramType = paramType;
	}

	public String getParamKey() {
		return paramKey;
	}

	public void setParamKey(String paramKey) {
		this.paramKey = paramKey;
	}

	public boolean isMapper() {
		return isMapper;
	}

	public void setMapper(boolean isMapper) {
		this.isMapper = isMapper;
	}

	@Override
	public String toString() {
		return "ParamMpper [paramType=" + paramType.getName() + ", paramKey=" + paramKey + ", isMapper=" + isMapper + "]";
	}
}

vo(实体对象): URequest.java         请求实体,假HttpServletRequest
package com.bo.example.vo;

import java.util.Map;

public class URequest {
	private String path ;
	private Map<String,Object> requestParam ;
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public Map<String, Object> getRequestParam() {
		return requestParam;
	}
	public void setRequestParam(Map<String, Object> requestParam) {
		this.requestParam = requestParam;
	}
}

vo(实体对象): User.java             用户实体
package com.bo.example.vo;

public class User {
	private String uid;
	private String uname;
	public String getUid() {
		return uid;
	}
	public void setUid(String uid) {
		this.uid = uid;
	}
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
	@Override
	public String toString() {
		return "User [uid=" + uid + ", uname=" + uname + "]";
	}
}
 

测试类:
package com.bo.example;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.bo.example.servlet.Servlet;
import com.bo.example.vo.URequest;
import com.bo.example.vo.User;

public class TestMain {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Servlet servlet = new Servlet();
		
		System.out.println("添加用户:");
		URequest  	addRequest = new URequest();
		addRequest.setPath("/user/add");
		Map<String,Object> userInfo = new HashMap<>();
		User u = new User();
		u.setUid("uid-0001");
		u.setUname("uname-0001");
		userInfo.put("userinfo", u);
		addRequest.setRequestParam(userInfo);
		Boolean result = (Boolean) servlet.doPost(addRequest);
		if(result){
			System.out.println("添加成功");
		}else{
			System.err.println("添加失败");
		}
		
		System.out.println("-------------------------------------------");
		System.out.println("所有用户列表:");
		URequest  	request = new URequest();
		request.setPath("/user/list");
		List<User> list = (List<User>)  servlet.doPost(request);
		
		for(int index = 0;index<list.size();index++){
			System.out.println(list.get(index).toString());
		}
	}

}

输出:
扫描开始---
扫描结束---
添加用户:
before ----
after----
添加成功
-------------------------------------------
所有用户列表:
before ----
after----
User [uid=uid000, uname=uname000]
User [uid=uid001, uname=uname001]
User [uid=uid002, uname=uname002]
User [uid=uid003, uname=uname003]
User [uid=uid004, uname=uname004]
User [uid=uid-0001, uname=uname-0001]

猜你喜欢

转载自blog.csdn.net/qq_28331477/article/details/51884174
今日推荐