您的位置:首页 > 编程语言 > Java开发

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);
}
}


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]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: