SpringMVC 包扫描+ C的模拟
2016-07-11 21:33
483 查看
今天在回顾代理模式时,发现了一些问题,联想到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 测试类
详细代码:
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);
}
}
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 测试类
详细代码:
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("扫描结束---"); } /** 4000 * 递归获取目录下所有.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]
相关文章推荐
- java查看字节码和jar文件命令
- Java中URLDecoder的编码问题
- java中创建线程的的几种方式
- JAVA学习笔记(一)
- springmvc拦截器实例
- SpringMVC(一)
- java基础知识
- 求同余幂
- java语言程序设计基础篇第九章编程练习题
- Java变量
- java访问修饰符
- struts2 学习路线
- Java注解——这些@圈圈都是个啥?
- 在Ubuntu 14.04 安装 JDK
- Java总结篇系列:Java多线程(三)
- struts2 插件使用
- Java phone,ip,idcard 获取地址信息
- Java中的Infinity和NaN
- JAVA基础类与对象实现模拟火车站购票功能
- Java总结篇系列:Java多线程(二)