From 285a59092fcbc329953a0be85203a0cc2cd2b53a Mon Sep 17 00:00:00 2001 From: monsoon <357703850@qq.com> Date: Tue, 18 Apr 2017 13:37:07 +0800 Subject: [PATCH 1/6] fix classutil bug and test beanIOC --- .../com/xfj/frameworktest/PropertiesLoad.java | 18 ------------- .../controller/CartController.java | 23 +++++++++++++++++ .../frameworktest/service/CartService.java | 11 ++++++++ .../com/xfj/frameworktest/util/world.java | 7 ------ .../src/test/java/PropertiesLoadTest.java | 25 +++++++++++++++++++ .../simple/xfj/framework/util/ClassUtil.java | 13 +++++++--- 6 files changed, 68 insertions(+), 29 deletions(-) delete mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/PropertiesLoad.java create mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java create mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java delete mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/util/world.java diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/PropertiesLoad.java b/frameworktest/src/main/java/com/xfj/frameworktest/PropertiesLoad.java deleted file mode 100644 index 6ee826c..0000000 --- a/frameworktest/src/main/java/com/xfj/frameworktest/PropertiesLoad.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.xfj.frameworktest; - -import org.junit.Test; -import simple.xfj.framework.annotation.Controller; -import simple.xfj.framework.constant.ConfigConstant; -import simple.xfj.framework.util.ClassUtil; -import simple.xfj.framework.util.PropsUtil; - -import java.util.Properties; - -/** - * Created by asus on 2017/4/17. - */ -@Controller -public class PropertiesLoad { - - -} diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java new file mode 100644 index 0000000..78f11b0 --- /dev/null +++ b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java @@ -0,0 +1,23 @@ +package com.xfj.frameworktest.controller; + +import com.xfj.frameworktest.service.CartService; +import simple.xfj.framework.annotation.Autowired; +import simple.xfj.framework.annotation.Controller; + +/** + * Created by asus on 2017/4/18. + */ +@Controller +public class CartController { + + @Autowired + private CartService cartService; + + public CartService getCartService() { + return cartService; + } + + public void setCartService(CartService cartService) { + this.cartService = cartService; + } +} diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java b/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java new file mode 100644 index 0000000..51d40dc --- /dev/null +++ b/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java @@ -0,0 +1,11 @@ +package com.xfj.frameworktest.service; + +import simple.xfj.framework.annotation.Service; + +/** + * Created by asus on 2017/4/18. + */ +@Service +public class CartService { + +} diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/util/world.java b/frameworktest/src/main/java/com/xfj/frameworktest/util/world.java deleted file mode 100644 index dd431c2..0000000 --- a/frameworktest/src/main/java/com/xfj/frameworktest/util/world.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.xfj.frameworktest.util; - -/** - * Created by asus on 2017/4/18. - */ -public class world { -} diff --git a/frameworktest/src/test/java/PropertiesLoadTest.java b/frameworktest/src/test/java/PropertiesLoadTest.java index 8b0b814..69f9c95 100644 --- a/frameworktest/src/test/java/PropertiesLoadTest.java +++ b/frameworktest/src/test/java/PropertiesLoadTest.java @@ -1,11 +1,16 @@ +import com.xfj.frameworktest.controller.CartController; +import com.xfj.frameworktest.service.CartService; import org.junit.Before; import org.junit.Test; import simple.xfj.framework.constant.ConfigConstant; +import simple.xfj.framework.helper.BeanHelper; import simple.xfj.framework.helper.ClassHelper; +import simple.xfj.framework.helper.IocHelper; import simple.xfj.framework.util.ClassUtil; import simple.xfj.framework.util.PropsUtil; import java.io.IOException; +import java.util.Map; import java.util.Properties; import java.util.Set; @@ -44,4 +49,24 @@ public void testGetControllerBean(){ } } + + + /** + * 测试cartservice是否依赖注入到cartcontroller中 + */ + @Test + public void testFrameWorkIOC()throws Exception{ + Set> beanSet = ClassHelper.getBeanSet(); + ClassUtil.loadClass(IocHelper.class.getName(),true); + Map, Object> beanMap = BeanHelper.getBeanMap(); + Set> keys = BeanHelper.getBeanMap().keySet(); + for(Class clazz : keys){ + System.out.println(clazz.getName()); + System.out.println(beanMap.get(clazz)); + } + CartController cartController = (CartController) beanMap.get(CartController.class); + System.out.println(cartController.getCartService() == beanMap.get(CartService.class) ); + + } + } diff --git a/src/main/java/simple/xfj/framework/util/ClassUtil.java b/src/main/java/simple/xfj/framework/util/ClassUtil.java index 62dd22d..5bbabce 100644 --- a/src/main/java/simple/xfj/framework/util/ClassUtil.java +++ b/src/main/java/simple/xfj/framework/util/ClassUtil.java @@ -92,6 +92,10 @@ private static void addClass(Set> set,String packagePath,String package public boolean accept(File f) { return f.isFile() && f.getName().endsWith(".class") || f.isDirectory(); }}); + //如果有空文件夹 需要跳过考虑 + if(files == null || files.length == 0){ + return; + } for(File f: files){ String fileName = f.getName(); if(f.isFile()){ @@ -102,12 +106,13 @@ public boolean accept(File f) { doAddClass(set,className); }else { //如果存在子文件夹,则递归读取子文件夹下的所有class文件,并加载 - String subPackageName = fileName; + String subPackageName = null; + String subPackagePath = null; if(packageName != null && packageName.length() >0){ - packageName = packageName + "." + subPackageName; - packagePath = packagePath + "/" + subPackageName; + subPackageName = packageName + "." + fileName; + subPackagePath = packagePath + "/" + fileName; } - addClass(set,packagePath,packageName); + addClass(set,subPackagePath,subPackageName); } } } From 3c22bbec66e5bfcc2e6c1ff0d53e53dbe6a4eb97 Mon Sep 17 00:00:00 2001 From: monsoon <357703850@qq.com> Date: Wed, 19 Apr 2017 00:57:02 +0800 Subject: [PATCH 2/6] start support dispatchServlet --- .../controller/CartController.java | 7 ++ .../src/test/java/PropertiesLoadTest.java | 16 ++++ .../xfj/framework/DispatcherServlet.java | 84 +++++++++++++++++++ .../xfj/framework/annotation/Action.java | 1 + .../java/simple/xfj/framework/bean/Data.java | 17 ++++ .../simple/xfj/framework/bean/Handler.java | 34 ++++++++ .../java/simple/xfj/framework/bean/Param.java | 20 +++++ .../simple/xfj/framework/bean/Request.java | 53 ++++++++++++ .../java/simple/xfj/framework/bean/View.java | 42 ++++++++++ .../framework/bootstarp/HelperInitiler.java | 27 ++++++ .../xfj/framework/constant/RequestMethod.java | 14 ++++ .../framework/helper/ControllerHelper.java | 49 +++++++++++ .../simple/xfj/framework/util/StreamUtil.java | 31 +++++++ 13 files changed, 395 insertions(+) create mode 100644 src/main/java/simple/xfj/framework/DispatcherServlet.java create mode 100644 src/main/java/simple/xfj/framework/bean/Data.java create mode 100644 src/main/java/simple/xfj/framework/bean/Handler.java create mode 100644 src/main/java/simple/xfj/framework/bean/Param.java create mode 100644 src/main/java/simple/xfj/framework/bean/Request.java create mode 100644 src/main/java/simple/xfj/framework/bean/View.java create mode 100644 src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java create mode 100644 src/main/java/simple/xfj/framework/constant/RequestMethod.java create mode 100644 src/main/java/simple/xfj/framework/helper/ControllerHelper.java create mode 100644 src/main/java/simple/xfj/framework/util/StreamUtil.java diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java index 78f11b0..d485af6 100644 --- a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java +++ b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java @@ -1,8 +1,10 @@ package com.xfj.frameworktest.controller; import com.xfj.frameworktest.service.CartService; +import simple.xfj.framework.annotation.Action; import simple.xfj.framework.annotation.Autowired; import simple.xfj.framework.annotation.Controller; +import simple.xfj.framework.constant.RequestMethod; /** * Created by asus on 2017/4/18. @@ -13,6 +15,11 @@ public class CartController { @Autowired private CartService cartService; + @Action(value = "/helloworld",method = RequestMethod.POST) + public void getRequest(){ + + } + public CartService getCartService() { return cartService; } diff --git a/frameworktest/src/test/java/PropertiesLoadTest.java b/frameworktest/src/test/java/PropertiesLoadTest.java index 69f9c95..86d3e60 100644 --- a/frameworktest/src/test/java/PropertiesLoadTest.java +++ b/frameworktest/src/test/java/PropertiesLoadTest.java @@ -2,9 +2,12 @@ import com.xfj.frameworktest.service.CartService; import org.junit.Before; import org.junit.Test; +import simple.xfj.framework.bean.Handler; +import simple.xfj.framework.bean.Request; import simple.xfj.framework.constant.ConfigConstant; import simple.xfj.framework.helper.BeanHelper; import simple.xfj.framework.helper.ClassHelper; +import simple.xfj.framework.helper.ControllerHelper; import simple.xfj.framework.helper.IocHelper; import simple.xfj.framework.util.ClassUtil; import simple.xfj.framework.util.PropsUtil; @@ -66,6 +69,19 @@ public void testFrameWorkIOC()throws Exception{ } CartController cartController = (CartController) beanMap.get(CartController.class); System.out.println(cartController.getCartService() == beanMap.get(CartService.class) ); + } + + @Test + public void testControllerHelper(){ + ClassUtil.loadClass(ControllerHelper.class.getName(),true); + Map actionMap = ControllerHelper.getActionMap(); + Set keys = actionMap.keySet(); + for(Request re : keys){ + System.out.println(re.getRequestPath()); + System.out.println(re.getRequestMethod()); + System.out.println(actionMap.get(re).getControllerClass().getName()); + System.out.println(actionMap.get(re).getActionMethod().getName()); + } } diff --git a/src/main/java/simple/xfj/framework/DispatcherServlet.java b/src/main/java/simple/xfj/framework/DispatcherServlet.java new file mode 100644 index 0000000..e7662db --- /dev/null +++ b/src/main/java/simple/xfj/framework/DispatcherServlet.java @@ -0,0 +1,84 @@ +package simple.xfj.framework; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import simple.xfj.framework.annotation.Action; +import simple.xfj.framework.bean.Handler; +import simple.xfj.framework.bean.Param; +import simple.xfj.framework.bean.Request; +import simple.xfj.framework.bootstarp.HelperInitiler; +import simple.xfj.framework.helper.BeanHelper; +import simple.xfj.framework.helper.ClassHelper; +import simple.xfj.framework.helper.ConfigHelper; +import simple.xfj.framework.helper.ControllerHelper; +import simple.xfj.framework.util.StreamUtil; + +import javax.servlet.*; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by asus on 2017/4/18. + */ +@WebServlet(urlPatterns = "/*",loadOnStartup = 0) +public class DispatcherServlet extends HttpServlet{ + + private static final Logger LOGGER = LoggerFactory.getLogger(DispatcherServlet.class); + + @Override + public void init(ServletConfig config) throws ServletException { + System.out.println("servlet start"); + //容器初始化 + HelperInitiler.init(); + ServletContext context = config.getServletContext(); + ServletRegistration jspServlet = context.getServletRegistration("jsp"); + jspServlet.addMapping(ConfigHelper.getAPPJspPath() + "*"); + ServletRegistration defaultServlet = context.getServletRegistration("default"); + defaultServlet.addMapping(ConfigHelper.getAPPAsset() + "*"); + } + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String method = req.getMethod().toLowerCase(); + String requestPath = req.getPathInfo(); + System.out.println(requestPath); + Request request = new Request(method,requestPath); + Handler handler = ControllerHelper.getActionMap().get(request); + if(null != handler){ + Class handlerClass = handler.getControllerClass(); + Object handlerBean = BeanHelper.getClassBean(handlerClass); + //创建param + System.out.println("yes"); + Param param = getParam(req); + } + } + + private Param getParam(HttpServletRequest req){ + Map paramMap = new HashMap(); + //URL中的参数收集 + Enumeration paramNames = req.getParameterNames(); + while (paramNames.hasMoreElements()){ + String name = paramNames.nextElement(); + String value = req.getParameter(name); + paramMap.put(name,value); + } + //form表单中的参数收集 + try { + String StringParam = StreamUtil.getStringFromStream(req.getInputStream()); + System.out.println(StringParam); + } catch (IOException e) { + LOGGER.error("read param from Stream failure"); + throw new RuntimeException(e); + } + return new Param(paramMap); + } + + +} diff --git a/src/main/java/simple/xfj/framework/annotation/Action.java b/src/main/java/simple/xfj/framework/annotation/Action.java index 6d59fe5..4a83787 100644 --- a/src/main/java/simple/xfj/framework/annotation/Action.java +++ b/src/main/java/simple/xfj/framework/annotation/Action.java @@ -12,4 +12,5 @@ @Retention(RetentionPolicy.RUNTIME) public @interface Action { String value(); + String method(); } diff --git a/src/main/java/simple/xfj/framework/bean/Data.java b/src/main/java/simple/xfj/framework/bean/Data.java new file mode 100644 index 0000000..17a75cf --- /dev/null +++ b/src/main/java/simple/xfj/framework/bean/Data.java @@ -0,0 +1,17 @@ +package simple.xfj.framework.bean; + +/** + * Created by asus on 2017/4/18. + */ +public class Data { + + private Object model; + + public Object getModel() { + return model; + } + + public void setModel(Object model) { + this.model = model; + } +} diff --git a/src/main/java/simple/xfj/framework/bean/Handler.java b/src/main/java/simple/xfj/framework/bean/Handler.java new file mode 100644 index 0000000..f8ed842 --- /dev/null +++ b/src/main/java/simple/xfj/framework/bean/Handler.java @@ -0,0 +1,34 @@ +package simple.xfj.framework.bean; + +import java.lang.reflect.Method; + +/** + * Created by asus on 2017/4/18. + */ +public class Handler { + + private Class controllerClass; + + private Method actionMethod; + + public Handler(Class controllerClass, Method actionMethod) { + this.controllerClass = controllerClass; + this.actionMethod = actionMethod; + } + + public Class getControllerClass() { + return controllerClass; + } + + public void setControllerClass(Class controllerClass) { + this.controllerClass = controllerClass; + } + + public Method getActionMethod() { + return actionMethod; + } + + public void setActionMethod(Method actionMethod) { + this.actionMethod = actionMethod; + } +} diff --git a/src/main/java/simple/xfj/framework/bean/Param.java b/src/main/java/simple/xfj/framework/bean/Param.java new file mode 100644 index 0000000..c192087 --- /dev/null +++ b/src/main/java/simple/xfj/framework/bean/Param.java @@ -0,0 +1,20 @@ +package simple.xfj.framework.bean; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by asus on 2017/4/18. + */ +public class Param { + + private Map paramMap = new HashMap(); + + public Param(Map paramMap) { + this.paramMap = paramMap; + } + + public Map getParamMap() { + return paramMap; + } +} diff --git a/src/main/java/simple/xfj/framework/bean/Request.java b/src/main/java/simple/xfj/framework/bean/Request.java new file mode 100644 index 0000000..2798b5e --- /dev/null +++ b/src/main/java/simple/xfj/framework/bean/Request.java @@ -0,0 +1,53 @@ +package simple.xfj.framework.bean; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +/** + * Created by asus on 2017/4/18. + */ +public class Request { + + private String requestMethod; + + private String requestPath; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Request request = (Request) o; + + if (!requestMethod.equals(request.requestMethod)) return false; + return requestPath.equals(request.requestPath); + } + + @Override + public int hashCode() { + int result = requestMethod.hashCode(); + result = 31 * result + requestPath.hashCode(); + return result; + } + + public String getRequestMethod() { + return requestMethod; + } + + public void setRequestMethod(String requestMethod) { + this.requestMethod = requestMethod; + } + + public String getRequestPath() { + return requestPath; + } + + public void setRequestPath(String requestPath) { + this.requestPath = requestPath; + } + + public Request(String requestMethod, String requestPath) { + this.requestMethod = requestMethod; + this.requestPath = requestPath; + } +} diff --git a/src/main/java/simple/xfj/framework/bean/View.java b/src/main/java/simple/xfj/framework/bean/View.java new file mode 100644 index 0000000..091c989 --- /dev/null +++ b/src/main/java/simple/xfj/framework/bean/View.java @@ -0,0 +1,42 @@ +package simple.xfj.framework.bean; + +import java.util.HashMap; +import java.util.Map; + +/** + * Created by asus on 2017/4/18. + */ +public class View { + + //返回视图路径 + private String path; + + //返回时所携带的数据模型 + private Map model; + + public View(String path, Map model) { + this.path = path; + this.model = model; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public Map getModel() { + return model; + } + + public void addMode(String key,Object obj){ + if(model == null){ + model = new HashMap(); + model.put(key,obj); + }else { + model.put(key,obj); + } + } +} diff --git a/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java b/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java new file mode 100644 index 0000000..065d310 --- /dev/null +++ b/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java @@ -0,0 +1,27 @@ +package simple.xfj.framework.bootstarp; + +import simple.xfj.framework.annotation.Controller; +import simple.xfj.framework.helper.BeanHelper; +import simple.xfj.framework.helper.ClassHelper; +import simple.xfj.framework.helper.IocHelper; +import simple.xfj.framework.util.ClassUtil; + +/** + * Created by asus on 2017/4/18. + */ +public class HelperInitiler { + + public static void init(){ + Class[] clazzs = new Class[]{ + ClassHelper.class, + BeanHelper.class, + IocHelper.class, + Controller.class + }; + + for(int i = 0;i < clazzs.length;i++){ + ClassUtil.loadClass(clazzs[i].getName(),true); + } + } + +} diff --git a/src/main/java/simple/xfj/framework/constant/RequestMethod.java b/src/main/java/simple/xfj/framework/constant/RequestMethod.java new file mode 100644 index 0000000..12b26c9 --- /dev/null +++ b/src/main/java/simple/xfj/framework/constant/RequestMethod.java @@ -0,0 +1,14 @@ +package simple.xfj.framework.constant; + +/** + * Created by asus on 2017/4/18. + */ +public final class RequestMethod { + + public static final String GET = "get"; + + public static final String POST = "post"; + + + +} diff --git a/src/main/java/simple/xfj/framework/helper/ControllerHelper.java b/src/main/java/simple/xfj/framework/helper/ControllerHelper.java new file mode 100644 index 0000000..c75b563 --- /dev/null +++ b/src/main/java/simple/xfj/framework/helper/ControllerHelper.java @@ -0,0 +1,49 @@ +package simple.xfj.framework.helper; + +import simple.xfj.framework.annotation.Action; +import simple.xfj.framework.bean.Handler; +import simple.xfj.framework.bean.Request; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * Created by asus on 2017/4/18. + */ +public final class ControllerHelper { + + /** + * 存放请求路径与处理器之间的映射关系 + */ + private static Map ACTION_MAP = new HashMap(); + + static { + Set> controllerSet = ClassHelper.getControllerSet(); + if(null != controllerSet && controllerSet.size() > 0){ + for(Class clazz : controllerSet){ + Method[] methods = clazz.getMethods(); + if(null != methods && methods.length > 0){ + for(Method method: methods){ + if(method.isAnnotationPresent(Action.class)){ + Action action = method.getAnnotation(Action.class); + String mapping = action.value(); + if(mapping.matches("^/.*") ){ + Request request = new Request(action.method(),mapping); + Handler handler = new Handler(clazz,method); + //将请求路径与处理的类的方法一一对应,联系起来 + ACTION_MAP.put(request,handler); + } + } + } + } + } + } + } + + public static Map getActionMap() { + return ACTION_MAP; + } +} diff --git a/src/main/java/simple/xfj/framework/util/StreamUtil.java b/src/main/java/simple/xfj/framework/util/StreamUtil.java new file mode 100644 index 0000000..f84e234 --- /dev/null +++ b/src/main/java/simple/xfj/framework/util/StreamUtil.java @@ -0,0 +1,31 @@ +package simple.xfj.framework.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * Created by asus on 2017/4/18. + */ +public class StreamUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(StreamUtil.class); + //从输入流中获得字符串 + public static String getStringFromStream(InputStream in){ + StringBuffer sb = new StringBuffer(); + try { + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + String line; + while ((line = reader.readLine())!= null){ + sb.append(line); + } + }catch (Exception e){ + LOGGER.error("read String from Stream failure"); + throw new RuntimeException(e); + } + return sb.toString(); + } + +} From 5ad46591cfe180dfcc4dfb7ffa6be824d4acd197 Mon Sep 17 00:00:00 2001 From: monsoon <357703850@qq.com> Date: Wed, 19 Apr 2017 13:19:52 +0800 Subject: [PATCH 3/6] finish dispatcherServlet --- .../xfj/framework/DispatcherServlet.java | 65 ++++++++++++++++--- .../simple/xfj/framework/util/DEcodeUtil.java | 42 ++++++++++++ .../simple/xfj/framework/util/JsonUtil.java | 41 ++++++++++++ .../xfj/framework/util/ReflectionUtil.java | 12 ++-- .../simple/xfj/framework/util/StreamUtil.java | 2 + 5 files changed, 147 insertions(+), 15 deletions(-) create mode 100644 src/main/java/simple/xfj/framework/util/DEcodeUtil.java create mode 100644 src/main/java/simple/xfj/framework/util/JsonUtil.java diff --git a/src/main/java/simple/xfj/framework/DispatcherServlet.java b/src/main/java/simple/xfj/framework/DispatcherServlet.java index e7662db..3fbbc1e 100644 --- a/src/main/java/simple/xfj/framework/DispatcherServlet.java +++ b/src/main/java/simple/xfj/framework/DispatcherServlet.java @@ -2,15 +2,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import simple.xfj.framework.annotation.Action; -import simple.xfj.framework.bean.Handler; -import simple.xfj.framework.bean.Param; -import simple.xfj.framework.bean.Request; +import simple.xfj.framework.bean.*; import simple.xfj.framework.bootstarp.HelperInitiler; import simple.xfj.framework.helper.BeanHelper; -import simple.xfj.framework.helper.ClassHelper; import simple.xfj.framework.helper.ConfigHelper; import simple.xfj.framework.helper.ControllerHelper; +import simple.xfj.framework.util.DEcodeUtil; +import simple.xfj.framework.util.JsonUtil; +import simple.xfj.framework.util.ReflectionUtil; import simple.xfj.framework.util.StreamUtil; import javax.servlet.*; @@ -19,10 +18,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.io.PrintWriter; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; -import java.util.Set; /** * Created by asus on 2017/4/18. @@ -55,8 +54,14 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws Class handlerClass = handler.getControllerClass(); Object handlerBean = BeanHelper.getClassBean(handlerClass); //创建param - System.out.println("yes"); Param param = getParam(req); + System.out.println(handler.getActionMethod().getName()); + Object res = ReflectionUtil.methodInvoke(handler.getActionMethod(), handlerBean, param); + try { + doResult(req,resp,res); + } catch (Exception e) { + e.printStackTrace(); + } } } @@ -71,8 +76,17 @@ private Param getParam(HttpServletRequest req){ } //form表单中的参数收集 try { - String StringParam = StreamUtil.getStringFromStream(req.getInputStream()); - System.out.println(StringParam); + String StringParam = DEcodeUtil.Decode(StreamUtil.getStringFromStream(req.getInputStream())); + if(StringParam.length() == 0) + return new Param(paramMap); + String[] nameValue = StringParam.split("&"); + if(nameValue != null && nameValue.length > 0){ + for(int i = 0; i < nameValue.length;i++){ + System.out.println(nameValue[i]); + String[] pair = nameValue[i].split("="); + paramMap.put(pair[0],pair[1]); + } + } } catch (IOException e) { LOGGER.error("read param from Stream failure"); throw new RuntimeException(e); @@ -81,4 +95,37 @@ private Param getParam(HttpServletRequest req){ } + private void doResult(HttpServletRequest req,HttpServletResponse pon,Object res) throws Exception{ + if(res == null){ + req.getRequestDispatcher(ConfigHelper.getAPPJspPath() + "error.jsp").forward(req,pon); + } + if(res instanceof View){ + View view = (View) res; + String path = view.getPath(); + if(path != null && path.length() > 0){ + if(path.startsWith("/")){ + pon.sendRedirect(req.getContextPath() + path); + }else{ + Map model = view.getModel(); + for(Map.Entry ele : model.entrySet()){ + req.setAttribute(ele.getKey(),ele.getValue()); + } + req.getRequestDispatcher(ConfigHelper.getAPPJspPath()).forward(req,pon); + } + } + }else if(res instanceof Data){ + //返回json数据 + Data data = (Data) res; + Object model = data.getModel(); + if(null != model){ + pon.setContentType("application/json"); + pon.setCharacterEncoding("UTF-8"); + PrintWriter writer = pon.getWriter(); + String json = JsonUtil.ObjToStr(model); + writer.write(json); + writer.flush(); + writer.close(); + } + } + } } diff --git a/src/main/java/simple/xfj/framework/util/DEcodeUtil.java b/src/main/java/simple/xfj/framework/util/DEcodeUtil.java new file mode 100644 index 0000000..0dada73 --- /dev/null +++ b/src/main/java/simple/xfj/framework/util/DEcodeUtil.java @@ -0,0 +1,42 @@ +package simple.xfj.framework.util; + +import com.sun.org.apache.xml.internal.utils.StringToStringTableVector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; + +/** + * Created by asus on 2017/4/19. + */ +public class DEcodeUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(DEcodeUtil.class); + + public static final String Decode(String str){ + String res = null; + try { + /* byte[] bytes = str.getBytes("ISO8859-1"); + res = new String(bytes, "GBK");*/ + res = URLDecoder.decode(str,"UTF-8"); + } catch (UnsupportedEncodingException e) { + LOGGER.error("decode String error"); + throw new RuntimeException(e); + } + return res; + } + + public static final String Encode(String str){ + try { + str = URLEncoder.encode(str,"ISO8859-1"); + } catch (UnsupportedEncodingException e) { + LOGGER.error("encode String error"); + throw new RuntimeException(e); + } + return str; + } + + +} diff --git a/src/main/java/simple/xfj/framework/util/JsonUtil.java b/src/main/java/simple/xfj/framework/util/JsonUtil.java new file mode 100644 index 0000000..ab0574b --- /dev/null +++ b/src/main/java/simple/xfj/framework/util/JsonUtil.java @@ -0,0 +1,41 @@ +package simple.xfj.framework.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * Created by asus on 2017/4/19. + */ +public class JsonUtil { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + private static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class); + + public static final String ObjToStr(Object object){ + String res = null; + try { + res = MAPPER.writeValueAsString(object); + } catch (JsonProcessingException e) { + LOGGER.error("transform object to json string failure"); + throw new RuntimeException(e); + } + return res; + } + + public static final T strToObj(String str,Class clazz){ + T t = null; + try { + t = MAPPER.readValue(str,clazz); + } catch (IOException e) { + LOGGER.error("parse json to obj string failure"); + throw new RuntimeException(e); + } + return t; + } + +} diff --git a/src/main/java/simple/xfj/framework/util/ReflectionUtil.java b/src/main/java/simple/xfj/framework/util/ReflectionUtil.java index 4e54eec..22ea5af 100644 --- a/src/main/java/simple/xfj/framework/util/ReflectionUtil.java +++ b/src/main/java/simple/xfj/framework/util/ReflectionUtil.java @@ -30,12 +30,12 @@ public static Object methodInvoke(Method method,Object obj,Object... args){ Object result = null; if(!method.isAccessible()){ method.setAccessible(true); - try { - result = method.invoke(obj,args); - } catch (Exception e) { - LOGGER.error("can not invoke method:" + method.getName()); - throw new RuntimeException("invoke method failure:" + method.getName()); - } + } + try { + result = method.invoke(obj,args); + } catch (Exception e) { + LOGGER.error("can not invoke method:" + method.getName()); + throw new RuntimeException("invoke method failure:" + method.getName()); } return result; } diff --git a/src/main/java/simple/xfj/framework/util/StreamUtil.java b/src/main/java/simple/xfj/framework/util/StreamUtil.java index f84e234..1b9e5de 100644 --- a/src/main/java/simple/xfj/framework/util/StreamUtil.java +++ b/src/main/java/simple/xfj/framework/util/StreamUtil.java @@ -21,6 +21,8 @@ public static String getStringFromStream(InputStream in){ while ((line = reader.readLine())!= null){ sb.append(line); } + reader.close(); + in.close(); }catch (Exception e){ LOGGER.error("read String from Stream failure"); throw new RuntimeException(e); From 2fd2fbe7207a9505d4f3674775129b5bd4bcc34c Mon Sep 17 00:00:00 2001 From: monsoon <357703850@qq.com> Date: Thu, 20 Apr 2017 00:27:34 +0800 Subject: [PATCH 4/6] dispatcherServlet test --- .../controller/CartController.java | 20 +++++++---- .../com/xfj/frameworktest/pojo/Student.java | 34 +++++++++++++++++++ 2 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/pojo/Student.java diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java index d485af6..9349fce 100644 --- a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java +++ b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java @@ -1,9 +1,12 @@ package com.xfj.frameworktest.controller; +import com.xfj.frameworktest.pojo.Student; import com.xfj.frameworktest.service.CartService; import simple.xfj.framework.annotation.Action; import simple.xfj.framework.annotation.Autowired; import simple.xfj.framework.annotation.Controller; +import simple.xfj.framework.bean.Data; +import simple.xfj.framework.bean.Param; import simple.xfj.framework.constant.RequestMethod; /** @@ -16,15 +19,18 @@ public class CartController { private CartService cartService; @Action(value = "/helloworld",method = RequestMethod.POST) - public void getRequest(){ - + public Data getRequest(Param param){ + Student s = new Student("xfh",24); + Data data = new Data(); + data.setModel(s); + return data; } - public CartService getCartService() { +public CartService getCartService() { return cartService; - } + } - public void setCartService(CartService cartService) { +public void setCartService(CartService cartService) { this.cartService = cartService; - } -} + } + } diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/pojo/Student.java b/frameworktest/src/main/java/com/xfj/frameworktest/pojo/Student.java new file mode 100644 index 0000000..3e7492b --- /dev/null +++ b/frameworktest/src/main/java/com/xfj/frameworktest/pojo/Student.java @@ -0,0 +1,34 @@ +package com.xfj.frameworktest.pojo; + +import java.io.InputStream; + +/** + * Created by asus on 2017/4/19. + */ +public class Student { + + private String name; + + private Integer age; + + public Student(String name, Integer age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } +} From acf5ce3fbd3a119cb50d759ae684a06336b4daeb Mon Sep 17 00:00:00 2001 From: monsoon <357703850@qq.com> Date: Thu, 20 Apr 2017 17:59:46 +0800 Subject: [PATCH 5/6] add AOP support with cglib --- .../xfj/frameworktest/aspect/TimeAspect.java | 31 +++++++ .../controller/CartController.java | 10 +-- pom.xml | 6 ++ .../xfj/framework/DispatcherServlet.java | 3 - .../xfj/framework/annotation/Aspect.java | 12 +++ .../framework/bootstarp/HelperInitiler.java | 2 + .../xfj/framework/helper/AopHelper.java | 90 +++++++++++++++++++ .../xfj/framework/helper/BeanHelper.java | 5 ++ .../xfj/framework/helper/ClassHelper.java | 33 +++++++ .../xfj/framework/proxy/AspectProxy.java | 58 ++++++++++++ .../simple/xfj/framework/proxy/Proxy.java | 9 ++ .../xfj/framework/proxy/ProxyChain.java | 60 +++++++++++++ .../xfj/framework/proxy/ProxyManager.java | 24 +++++ .../xfj/framework/util/ReflectionUtil.java | 4 +- 14 files changed, 337 insertions(+), 10 deletions(-) create mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java create mode 100644 src/main/java/simple/xfj/framework/annotation/Aspect.java create mode 100644 src/main/java/simple/xfj/framework/helper/AopHelper.java create mode 100644 src/main/java/simple/xfj/framework/proxy/AspectProxy.java create mode 100644 src/main/java/simple/xfj/framework/proxy/Proxy.java create mode 100644 src/main/java/simple/xfj/framework/proxy/ProxyChain.java create mode 100644 src/main/java/simple/xfj/framework/proxy/ProxyManager.java diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java b/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java new file mode 100644 index 0000000..c0269d5 --- /dev/null +++ b/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java @@ -0,0 +1,31 @@ +package com.xfj.frameworktest.aspect; + +import simple.xfj.framework.annotation.Aspect; +import simple.xfj.framework.annotation.Controller; +import simple.xfj.framework.proxy.AspectProxy; + +import java.lang.reflect.Method; + +/** + * Created by asus on 2017/4/20. + */ +@Aspect(value = Controller.class)//声明这个类是增强类,并且去拦截被所有被controller标注的类的方法 +public class TimeAspect extends AspectProxy{ + @Override + public void before(Class cls, Method method, Object[] params) throws Throwable { + super.before(cls, method, params); + System.out.println("前置增强"); + System.out.println(System.currentTimeMillis()); + } + + @Override + public void after(Class cls, Method method, Object[] params, Object result) throws Throwable { + super.after(cls, method, params, result); + System.out.println("后置增强"); + System.out.println(System.currentTimeMillis()); + } + + public static void main(String[] agrs){ + System.out.println(AspectProxy.class.isAssignableFrom(TimeAspect.class)); + } +} diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java index 9349fce..656dafa 100644 --- a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java +++ b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java @@ -18,7 +18,7 @@ public class CartController { @Autowired private CartService cartService; - @Action(value = "/helloworld",method = RequestMethod.POST) + @Action(value = "/helloworld",method = RequestMethod.GET) public Data getRequest(Param param){ Student s = new Student("xfh",24); Data data = new Data(); @@ -26,11 +26,11 @@ public Data getRequest(Param param){ return data; } -public CartService getCartService() { + public CartService getCartService() { return cartService; } -public void setCartService(CartService cartService) { + public void setCartService(CartService cartService) { this.cartService = cartService; - } - } + } +} diff --git a/pom.xml b/pom.xml index 337dc02..779eaef 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,12 @@ commons-dbcp 1.4 + + + cglib + cglib + 2.2.2 + diff --git a/src/main/java/simple/xfj/framework/DispatcherServlet.java b/src/main/java/simple/xfj/framework/DispatcherServlet.java index 3fbbc1e..e97a299 100644 --- a/src/main/java/simple/xfj/framework/DispatcherServlet.java +++ b/src/main/java/simple/xfj/framework/DispatcherServlet.java @@ -47,7 +47,6 @@ public void init(ServletConfig config) throws ServletException { protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod().toLowerCase(); String requestPath = req.getPathInfo(); - System.out.println(requestPath); Request request = new Request(method,requestPath); Handler handler = ControllerHelper.getActionMap().get(request); if(null != handler){ @@ -55,7 +54,6 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws Object handlerBean = BeanHelper.getClassBean(handlerClass); //创建param Param param = getParam(req); - System.out.println(handler.getActionMethod().getName()); Object res = ReflectionUtil.methodInvoke(handler.getActionMethod(), handlerBean, param); try { doResult(req,resp,res); @@ -82,7 +80,6 @@ private Param getParam(HttpServletRequest req){ String[] nameValue = StringParam.split("&"); if(nameValue != null && nameValue.length > 0){ for(int i = 0; i < nameValue.length;i++){ - System.out.println(nameValue[i]); String[] pair = nameValue[i].split("="); paramMap.put(pair[0],pair[1]); } diff --git a/src/main/java/simple/xfj/framework/annotation/Aspect.java b/src/main/java/simple/xfj/framework/annotation/Aspect.java new file mode 100644 index 0000000..9be635b --- /dev/null +++ b/src/main/java/simple/xfj/framework/annotation/Aspect.java @@ -0,0 +1,12 @@ +package simple.xfj.framework.annotation; + +import java.lang.annotation.*; + +/** + * Created by asus on 2017/4/20. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Aspect { + Class value(); +} diff --git a/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java b/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java index 065d310..6d4797b 100644 --- a/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java +++ b/src/main/java/simple/xfj/framework/bootstarp/HelperInitiler.java @@ -1,6 +1,7 @@ package simple.xfj.framework.bootstarp; import simple.xfj.framework.annotation.Controller; +import simple.xfj.framework.helper.AopHelper; import simple.xfj.framework.helper.BeanHelper; import simple.xfj.framework.helper.ClassHelper; import simple.xfj.framework.helper.IocHelper; @@ -15,6 +16,7 @@ public static void init(){ Class[] clazzs = new Class[]{ ClassHelper.class, BeanHelper.class, + AopHelper.class,// AopHelper要在beanHelper之后,IocHelper之前初始化 IocHelper.class, Controller.class }; diff --git a/src/main/java/simple/xfj/framework/helper/AopHelper.java b/src/main/java/simple/xfj/framework/helper/AopHelper.java new file mode 100644 index 0000000..321e9df --- /dev/null +++ b/src/main/java/simple/xfj/framework/helper/AopHelper.java @@ -0,0 +1,90 @@ +package simple.xfj.framework.helper; + +import simple.xfj.framework.annotation.Aspect; +import simple.xfj.framework.proxy.AspectProxy; +import simple.xfj.framework.proxy.Proxy; +import simple.xfj.framework.proxy.ProxyManager; +import simple.xfj.framework.util.ReflectionUtil; + +import java.lang.annotation.Annotation; +import java.util.*; + +/** + * Created by asus on 2017/4/20. + */ +public class AopHelper { + + static { + //类加载时初始化AOP,并将其设置到Bean中 + Map, List> target2ProxyList = getTarget2ProxyList(); + if(null != target2ProxyList && target2ProxyList.size() > 0){ + Set, List>> entries = target2ProxyList.entrySet(); + for(Map.Entry, List> entry: entries){ + Class clazz = entry.getKey(); + List proxyList = entry.getValue(); + Object bean = ProxyManager.getProxy(clazz, proxyList); + BeanHelper.setBean(clazz,bean); + } + } + } + + /** + * 获取切面要去增强的所有类 + * @param aspect + * @return + */ + private static Set> getTargetClassSet(Aspect aspect){ + Set> targetClass = new HashSet>(); + if(aspect != null){ + Class annotation = aspect.value(); + if(annotation != null && !annotation.equals(Aspect.class)){ + Set> classSetByAnnoation = ClassHelper.getClassSetByAnnoation(annotation); + targetClass.addAll(classSetByAnnoation); + } + } + return targetClass; + } + + /** + * 获取所有的切面类aspest与目标类的映射关系 + */ + + private static Map, Set>> getAspect2Target(){ + Map, Set>> proxyMap = new HashMap, Set>>(); + Set> aspectClassSet = ClassHelper.getClassSetBySuper(AspectProxy.class); + for(Class clazz : aspectClassSet){ + if(clazz.isAnnotationPresent(Aspect.class)){ + Aspect aspect = (Aspect)clazz.getAnnotation(Aspect.class); + Set> classSet = getTargetClassSet(aspect); + proxyMap.put(clazz,classSet); + } + } + return proxyMap; + } + + /** + * 将每个目标类所需要增强的增强类整理成1对多的map集合以便在beanHelper中用去取代原来的原始bean + * @return + */ + private static Map,List> getTarget2ProxyList(){ + Map,List> clazz4Proxy = new HashMap, List>(); + Map, Set>> aspect2Target = getAspect2Target(); + Set, Set>>> entries = aspect2Target.entrySet(); + for(Map.Entry, Set>> entry : entries){ + Class proxyClass = entry.getKey(); + Set> targetSet = entry.getValue(); + for(Class cls : targetSet){ + List proxies = clazz4Proxy.get(cls); + if(null == proxies){ + proxies = new ArrayList(); + proxies.add(ReflectionUtil.newInstance(proxyClass)); + clazz4Proxy.put(cls,proxies); + }else{ + proxies.add(ReflectionUtil.newInstance(proxyClass)); + } + } + } + return clazz4Proxy; + } + +} diff --git a/src/main/java/simple/xfj/framework/helper/BeanHelper.java b/src/main/java/simple/xfj/framework/helper/BeanHelper.java index 4f0e285..5bebaa8 100644 --- a/src/main/java/simple/xfj/framework/helper/BeanHelper.java +++ b/src/main/java/simple/xfj/framework/helper/BeanHelper.java @@ -36,4 +36,9 @@ public static T getClassBean(Class clazz){ } return null; } + + public static void setBean(Class clazz,Object object){ + //用于在aop生成代理类后,替换bean容器里的原有目标类, + beanMap.put(clazz,object); + } } diff --git a/src/main/java/simple/xfj/framework/helper/ClassHelper.java b/src/main/java/simple/xfj/framework/helper/ClassHelper.java index 3415180..eae5a62 100644 --- a/src/main/java/simple/xfj/framework/helper/ClassHelper.java +++ b/src/main/java/simple/xfj/framework/helper/ClassHelper.java @@ -10,6 +10,7 @@ import simple.xfj.framework.annotation.Service; import simple.xfj.framework.util.ClassUtil; +import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Set; @@ -76,4 +77,36 @@ public static Set> getBeanSet(){ return beanSet; } + + /** + * 获得某个父类下的所有子类 + * @param clazz + * @return + */ + public static Set> getClassSetBySuper(Class clazz){ + Set> classSet = new HashSet>(); + for(Class cls : CLAZZ_SET){ + if(clazz.isAssignableFrom(cls) && !cls.equals(clazz)){ + classSet.add(cls); + } + } + return classSet; + } + + /** + * 获取被某个注解注释的类 + * @param annoationClass + * @return + */ + public static Set> getClassSetByAnnoation(Class annoationClass){ + Set> classSet = new HashSet>(); + for(Class cls : CLAZZ_SET){ + if(cls.isAnnotationPresent(annoationClass)){ + classSet.add(cls); + } + } + return classSet; + } + + } diff --git a/src/main/java/simple/xfj/framework/proxy/AspectProxy.java b/src/main/java/simple/xfj/framework/proxy/AspectProxy.java new file mode 100644 index 0000000..74afd01 --- /dev/null +++ b/src/main/java/simple/xfj/framework/proxy/AspectProxy.java @@ -0,0 +1,58 @@ +package simple.xfj.framework.proxy; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; + +/** + * Created by asus on 2017/4/20. + */ +public class AspectProxy implements Proxy{ + + + private static final Logger LOGGER = LoggerFactory.getLogger(AspectProxy.class); + + public Object doProxy(ProxyChain proxyChain) throws Throwable { + Object res = null; + Class targetClass = proxyChain.getTargetClass(); + Object[] methodParams = proxyChain.getMethodParams(); + Method targetMethod = proxyChain.getTargetMethod(); + begin(); + try{ + if(intercept(targetClass,targetMethod,methodParams)){ + before(targetClass,targetMethod,methodParams); + res = proxyChain.doProxyChain(); + after(targetClass,targetMethod,methodParams,res); + }else{ + res = proxyChain.doProxyChain(); + } + }catch (Exception e){ + LOGGER.error("invoke method chain proxy error" + targetMethod.getName()); + throw e; + }finally { + end(); + } + return res; + } + public void begin(){ + + } + + public boolean intercept(Class cls,Method method,Object[] params) throws Throwable{ + return true; + } + public void before(Class cls,Method method,Object[] params) throws Throwable{ + System.out.println("ni hao"); + + } + + public void after(Class cls,Method method,Object[] params,Object result) throws Throwable{ + System.out.println("ni huai"); + } + public void end(){ + + } + + +} diff --git a/src/main/java/simple/xfj/framework/proxy/Proxy.java b/src/main/java/simple/xfj/framework/proxy/Proxy.java new file mode 100644 index 0000000..bc596df --- /dev/null +++ b/src/main/java/simple/xfj/framework/proxy/Proxy.java @@ -0,0 +1,9 @@ +package simple.xfj.framework.proxy; + +/** + * Created by asus on 2017/4/20. + */ +public interface Proxy { + + Object doProxy(ProxyChain proxyChain) throws Throwable; +} diff --git a/src/main/java/simple/xfj/framework/proxy/ProxyChain.java b/src/main/java/simple/xfj/framework/proxy/ProxyChain.java new file mode 100644 index 0000000..bc1592a --- /dev/null +++ b/src/main/java/simple/xfj/framework/proxy/ProxyChain.java @@ -0,0 +1,60 @@ +package simple.xfj.framework.proxy; + +import net.sf.cglib.proxy.MethodProxy; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by asus on 2017/4/20. + */ +public class ProxyChain { + + private final Class targetClass; + private final Object target; + private final Method targetMethod; + private final MethodProxy methodProxy; + private final Object[] methodParams; + + private List proxyList = new ArrayList(); + + private int proxyIndex = 0; + + public ProxyChain(Class targetClass, Object target, Method targetMethod, MethodProxy methodProxy, Object[] methodParams) { + this.targetClass = targetClass; + this.target = target; + this.targetMethod = targetMethod; + this.methodProxy = methodProxy; + this.methodParams = methodParams; + } + + public Class getTargetClass() { + return targetClass; + } + + public Method getTargetMethod() { + return targetMethod; + } + + public Object[] getMethodParams() { + return methodParams; + } + + public ProxyChain setProxyList(List proxyList){ + this.proxyList = proxyList; + return this; + } + + public Object doProxyChain() throws Throwable{ + Object res = null; + if(null != proxyList && proxyIndex < proxyList.size()){ + //将链条中的代理一个一个的添加到代理方法中 + res = proxyList.get(proxyIndex++).doProxy(this); + }else{ + res = methodProxy.invokeSuper(target,methodParams); + } + return res; + } + +} diff --git a/src/main/java/simple/xfj/framework/proxy/ProxyManager.java b/src/main/java/simple/xfj/framework/proxy/ProxyManager.java new file mode 100644 index 0000000..f7e45f9 --- /dev/null +++ b/src/main/java/simple/xfj/framework/proxy/ProxyManager.java @@ -0,0 +1,24 @@ +package simple.xfj.framework.proxy; + +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * Created by asus on 2017/4/20. + */ +public class ProxyManager { + + //产生代理的管理类 + public static T getProxy(final Class clazz , final List proxyList){ + return (T)Enhancer.create(clazz, new MethodInterceptor() { + public Object intercept(Object target, Method method, Object[] agrs, MethodProxy methodProxy) throws Throwable { + return new ProxyChain(clazz,target,method,methodProxy,agrs).setProxyList(proxyList).doProxyChain(); + } + }); + } + +} diff --git a/src/main/java/simple/xfj/framework/util/ReflectionUtil.java b/src/main/java/simple/xfj/framework/util/ReflectionUtil.java index 22ea5af..d2a022c 100644 --- a/src/main/java/simple/xfj/framework/util/ReflectionUtil.java +++ b/src/main/java/simple/xfj/framework/util/ReflectionUtil.java @@ -15,7 +15,7 @@ public class ReflectionUtil { private static Logger LOGGER = LoggerFactory.getLogger(ReflectionUtil.class); - public static Object newInstance(Class clazz){ + public static T newInstance(Class clazz){ Object obj = null; try { obj = clazz.newInstance(); @@ -23,7 +23,7 @@ public static Object newInstance(Class clazz){ LOGGER.error("can new " + clazz.getName()); throw new RuntimeException(e); } - return obj; + return (T)obj; } public static Object methodInvoke(Method method,Object obj,Object... args){ From 53554921a7a4c2b6e9a526afe6ddbab25339794f Mon Sep 17 00:00:00 2001 From: monsoon <357703850@qq.com> Date: Fri, 21 Apr 2017 14:26:42 +0800 Subject: [PATCH 6/6] support regex expression Pointcut Aop Aspect --- .../xfj/frameworktest/aspect/TimeAspect.java | 4 ++ .../controller/CartController.java | 16 ++++- .../frameworktest/service/CartService.java | 4 ++ .../frameworktest/service/StudentService.java | 11 +++ .../src/test/java/PropertiesLoadTest.java | 8 +++ .../xfj/framework/DispatcherServlet.java | 8 ++- .../xfj/framework/annotation/Execution.java | 16 +++++ .../simple/xfj/framework/bean/RegexSet.java | 34 ++++++++++ .../java/simple/xfj/framework/bean/View.java | 4 ++ .../xfj/framework/helper/AopHelper.java | 68 +++++++++++++++---- .../xfj/framework/helper/ClassHelper.java | 28 ++++++++ .../xfj/framework/proxy/AspectProxy.java | 26 ++++++- .../simple/xfj/framework/proxy/Proxy.java | 14 +++- 13 files changed, 221 insertions(+), 20 deletions(-) create mode 100644 frameworktest/src/main/java/com/xfj/frameworktest/service/StudentService.java create mode 100644 src/main/java/simple/xfj/framework/annotation/Execution.java create mode 100644 src/main/java/simple/xfj/framework/bean/RegexSet.java diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java b/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java index c0269d5..9f310c3 100644 --- a/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java +++ b/frameworktest/src/main/java/com/xfj/frameworktest/aspect/TimeAspect.java @@ -2,6 +2,7 @@ import simple.xfj.framework.annotation.Aspect; import simple.xfj.framework.annotation.Controller; +import simple.xfj.framework.annotation.Execution; import simple.xfj.framework.proxy.AspectProxy; import java.lang.reflect.Method; @@ -10,10 +11,12 @@ * Created by asus on 2017/4/20. */ @Aspect(value = Controller.class)//声明这个类是增强类,并且去拦截被所有被controller标注的类的方法 +//@Execution(value = "com.xfj.frameworktest.*find.*") //com.xfj.frameworktest包下所有类以good开头的方法 public class TimeAspect extends AspectProxy{ @Override public void before(Class cls, Method method, Object[] params) throws Throwable { super.before(cls, method, params); + System.out.println(cls.getName() + "." + method.getName()); System.out.println("前置增强"); System.out.println(System.currentTimeMillis()); } @@ -22,6 +25,7 @@ public void before(Class cls, Method method, Object[] params) throws Throwabl public void after(Class cls, Method method, Object[] params, Object result) throws Throwable { super.after(cls, method, params, result); System.out.println("后置增强"); + System.out.println(cls.getName() + "." + method.getName()); System.out.println(System.currentTimeMillis()); } diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java index 656dafa..496fba8 100644 --- a/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java +++ b/frameworktest/src/main/java/com/xfj/frameworktest/controller/CartController.java @@ -7,6 +7,7 @@ import simple.xfj.framework.annotation.Controller; import simple.xfj.framework.bean.Data; import simple.xfj.framework.bean.Param; +import simple.xfj.framework.bean.View; import simple.xfj.framework.constant.RequestMethod; /** @@ -15,14 +16,26 @@ @Controller public class CartController { + private static int i = 0; + @Autowired private CartService cartService; @Action(value = "/helloworld",method = RequestMethod.GET) - public Data getRequest(Param param){ + public View getRequest(Param param){ Student s = new Student("xfh",24); Data data = new Data(); data.setModel(s); + View view = new View("error.jsp",null); + return view; + } + + @Action(value = "/findname",method = RequestMethod.GET) + public Data findName(Param param){ + Student s = new Student("xfh",25); + Data data = new Data(); + data.setModel(s); + System.out.println(i++); return data; } @@ -33,4 +46,5 @@ public CartService getCartService() { public void setCartService(CartService cartService) { this.cartService = cartService; } + } diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java b/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java index 51d40dc..e5a8d12 100644 --- a/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java +++ b/frameworktest/src/main/java/com/xfj/frameworktest/service/CartService.java @@ -8,4 +8,8 @@ @Service public class CartService { + public void xfindUserByName(){ + + } + } diff --git a/frameworktest/src/main/java/com/xfj/frameworktest/service/StudentService.java b/frameworktest/src/main/java/com/xfj/frameworktest/service/StudentService.java new file mode 100644 index 0000000..147b58e --- /dev/null +++ b/frameworktest/src/main/java/com/xfj/frameworktest/service/StudentService.java @@ -0,0 +1,11 @@ +package com.xfj.frameworktest.service; + +/** + * Created by asus on 2017/4/21. + */ +public class StudentService { + + public void xfindStudentById(){ + + } +} diff --git a/frameworktest/src/test/java/PropertiesLoadTest.java b/frameworktest/src/test/java/PropertiesLoadTest.java index 86d3e60..a7b5a7b 100644 --- a/frameworktest/src/test/java/PropertiesLoadTest.java +++ b/frameworktest/src/test/java/PropertiesLoadTest.java @@ -82,7 +82,15 @@ public void testControllerHelper(){ System.out.println(actionMap.get(re).getControllerClass().getName()); System.out.println(actionMap.get(re).getActionMethod().getName()); } + } + @Test + public void testRegexMatchClass(){ + ClassUtil.loadClass(ClassHelper.class.getName(),true); + Set> classSet = ClassHelper.getClassSetByMatchMethodName("com.xfj.frameworktest.*find.*"); + for(Class cls : classSet){ + System.out.println(cls.getName()); + } } } diff --git a/src/main/java/simple/xfj/framework/DispatcherServlet.java b/src/main/java/simple/xfj/framework/DispatcherServlet.java index e97a299..cd5da93 100644 --- a/src/main/java/simple/xfj/framework/DispatcherServlet.java +++ b/src/main/java/simple/xfj/framework/DispatcherServlet.java @@ -104,10 +104,12 @@ private void doResult(HttpServletRequest req,HttpServletResponse pon,Object res) pon.sendRedirect(req.getContextPath() + path); }else{ Map model = view.getModel(); - for(Map.Entry ele : model.entrySet()){ - req.setAttribute(ele.getKey(),ele.getValue()); + if(model != null && model.size()>0){ + for(Map.Entry ele : model.entrySet()){ + req.setAttribute(ele.getKey(),ele.getValue()); + } } - req.getRequestDispatcher(ConfigHelper.getAPPJspPath()).forward(req,pon); + req.getRequestDispatcher(ConfigHelper.getAPPJspPath() + path).forward(req,pon); } } }else if(res instanceof Data){ diff --git a/src/main/java/simple/xfj/framework/annotation/Execution.java b/src/main/java/simple/xfj/framework/annotation/Execution.java new file mode 100644 index 0000000..ce30757 --- /dev/null +++ b/src/main/java/simple/xfj/framework/annotation/Execution.java @@ -0,0 +1,16 @@ +package simple.xfj.framework.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Created by asus on 2017/4/21. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Execution +{ + String value(); +} diff --git a/src/main/java/simple/xfj/framework/bean/RegexSet.java b/src/main/java/simple/xfj/framework/bean/RegexSet.java new file mode 100644 index 0000000..8419010 --- /dev/null +++ b/src/main/java/simple/xfj/framework/bean/RegexSet.java @@ -0,0 +1,34 @@ +package simple.xfj.framework.bean; + +import java.util.Set; + +/** + * Created by asus on 2017/4/21. + */ +public class RegexSet{ + String regex; + + Set> classSet; + + public RegexSet(String regex, Set> classSet) { + this.regex = regex; + this.classSet = classSet; + } + + + public String getRegex() { + return regex; + } + + public void setRegex(String regex) { + this.regex = regex; + } + + public Set> getClassSet() { + return classSet; + } + + public void setClassSet(Set> classSet) { + this.classSet = classSet; + } +} diff --git a/src/main/java/simple/xfj/framework/bean/View.java b/src/main/java/simple/xfj/framework/bean/View.java index 091c989..2fa2a4d 100644 --- a/src/main/java/simple/xfj/framework/bean/View.java +++ b/src/main/java/simple/xfj/framework/bean/View.java @@ -19,6 +19,10 @@ public View(String path, Map model) { this.model = model; } + public View() { + + } + public String getPath() { return path; } diff --git a/src/main/java/simple/xfj/framework/helper/AopHelper.java b/src/main/java/simple/xfj/framework/helper/AopHelper.java index 321e9df..55be708 100644 --- a/src/main/java/simple/xfj/framework/helper/AopHelper.java +++ b/src/main/java/simple/xfj/framework/helper/AopHelper.java @@ -1,6 +1,8 @@ package simple.xfj.framework.helper; import simple.xfj.framework.annotation.Aspect; +import simple.xfj.framework.annotation.Execution; +import simple.xfj.framework.bean.RegexSet; import simple.xfj.framework.proxy.AspectProxy; import simple.xfj.framework.proxy.Proxy; import simple.xfj.framework.proxy.ProxyManager; @@ -33,7 +35,7 @@ public class AopHelper { * @param aspect * @return */ - private static Set> getTargetClassSet(Aspect aspect){ + private static RegexSet getTargetClassSet(Aspect aspect){ Set> targetClass = new HashSet>(); if(aspect != null){ Class annotation = aspect.value(); @@ -42,21 +44,43 @@ private static Set> getTargetClassSet(Aspect aspect){ targetClass.addAll(classSetByAnnoation); } } - return targetClass; + if(targetClass != null && targetClass.size() > 0){ + return new RegexSet(null,targetClass); + } + return null; + } + + + private static RegexSet getTargetClassSetByRegex(Execution execution){ + if(null != execution){ + String regex = execution.value(); + if(regex != null && regex.length() > 0){ + Set> classSet = ClassHelper.getClassSetByMatchMethodName(regex); + if(classSet != null && classSet.size()>0){ + return new RegexSet(regex,classSet); + } + } + } + return null; } /** * 获取所有的切面类aspest与目标类的映射关系 */ - private static Map, Set>> getAspect2Target(){ - Map, Set>> proxyMap = new HashMap, Set>>(); + private static Map, RegexSet> getAspect2Target(){ + Map, RegexSet> proxyMap = new HashMap, RegexSet>(); Set> aspectClassSet = ClassHelper.getClassSetBySuper(AspectProxy.class); for(Class clazz : aspectClassSet){ if(clazz.isAnnotationPresent(Aspect.class)){ Aspect aspect = (Aspect)clazz.getAnnotation(Aspect.class); - Set> classSet = getTargetClassSet(aspect); - proxyMap.put(clazz,classSet); + RegexSet regexAllSet = getTargetClassSet(aspect); + proxyMap.put(clazz,regexAllSet); + } + if(clazz.isAnnotationPresent(Execution.class)){ + Execution execution = (Execution)clazz.getAnnotation(Execution.class); + RegexSet regexStringSet = getTargetClassSetByRegex(execution); + proxyMap.put(clazz,regexStringSet); // classSet 与 regexClassSet可能会有重复 } } return proxyMap; @@ -68,12 +92,32 @@ private static Map, Set>> getAspect2Target(){ */ private static Map,List> getTarget2ProxyList(){ Map,List> clazz4Proxy = new HashMap, List>(); - Map, Set>> aspect2Target = getAspect2Target(); - Set, Set>>> entries = aspect2Target.entrySet(); - for(Map.Entry, Set>> entry : entries){ + Map, RegexSet> aspect2Target = getAspect2Target(); + Set, RegexSet>> entries = aspect2Target.entrySet(); + for(Map.Entry, RegexSet> entry : entries){ Class proxyClass = entry.getKey(); - Set> targetSet = entry.getValue(); - for(Class cls : targetSet){ + RegexSet targetSet = entry.getValue(); + if(targetSet != null){ + String regex = targetSet.getRegex(); + Set> classes = targetSet.getClassSet(); + if(classes != null && classes.size() >0){ + for(Class cls : classes){ + List proxies = clazz4Proxy.get(cls); + if(null == proxies){ + proxies = new ArrayList(); + Proxy reproxy = ReflectionUtil.newInstance(proxyClass); + reproxy.setRegex(regex); + proxies.add(reproxy); + clazz4Proxy.put(cls,proxies); + }else{ + Proxy reproxy = ReflectionUtil.newInstance(proxyClass); + reproxy.setRegex(regex); + proxies.add(reproxy); + } + } + } + } + /* for(Class cls : targetSet){ List proxies = clazz4Proxy.get(cls); if(null == proxies){ proxies = new ArrayList(); @@ -82,7 +126,7 @@ private static Map,List> getTarget2ProxyList(){ }else{ proxies.add(ReflectionUtil.newInstance(proxyClass)); } - } + }*/ } return clazz4Proxy; } diff --git a/src/main/java/simple/xfj/framework/helper/ClassHelper.java b/src/main/java/simple/xfj/framework/helper/ClassHelper.java index eae5a62..4fdc971 100644 --- a/src/main/java/simple/xfj/framework/helper/ClassHelper.java +++ b/src/main/java/simple/xfj/framework/helper/ClassHelper.java @@ -11,8 +11,10 @@ import simple.xfj.framework.util.ClassUtil; import java.lang.annotation.Annotation; +import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; +import java.util.regex.Pattern; /** * 获取指定包名下的各种注解类的helper类 @@ -109,4 +111,30 @@ public static Set> getClassSetByAnnoation(Class a } + /** + * 根据正则选取正则匹配方法名的class类 + * @param regex + * @return + */ + public static Set> getClassSetByMatchMethodName(String regex){ + Set> classSet = new HashSet>(); + Pattern pattern = Pattern.compile(regex); + for(Class cls : CLAZZ_SET){ + String clsName = cls.getName(); + Method[] methods = cls.getDeclaredMethods(); + if(methods != null && methods.length > 0){ + for(Method method : methods){ + String methodName = clsName + "." + method.getName().toLowerCase(); + if(pattern.matcher(methodName).matches()){ + classSet.add(cls); + //只要添加一次就可以了 + break; + } + } + } + } + return classSet; + } + + } diff --git a/src/main/java/simple/xfj/framework/proxy/AspectProxy.java b/src/main/java/simple/xfj/framework/proxy/AspectProxy.java index 74afd01..86c671f 100644 --- a/src/main/java/simple/xfj/framework/proxy/AspectProxy.java +++ b/src/main/java/simple/xfj/framework/proxy/AspectProxy.java @@ -4,11 +4,12 @@ import org.slf4j.LoggerFactory; import java.lang.reflect.Method; +import java.util.regex.Pattern; /** * Created by asus on 2017/4/20. */ -public class AspectProxy implements Proxy{ +public class AspectProxy extends Proxy{ private static final Logger LOGGER = LoggerFactory.getLogger(AspectProxy.class); @@ -40,8 +41,29 @@ public void begin(){ } public boolean intercept(Class cls,Method method,Object[] params) throws Throwable{ - return true; + if(super.getRegex() == null) { + //对@Aspect注解的类的所有方法进行增强,其他的如@Execution的注解进行拦截判断 + Method[] declaredMethods = cls.getDeclaredMethods(); + if(null != declaredMethods && declaredMethods.length > 0){ + for(int i = 0;i< declaredMethods.length;i++){ + if(method.equals(declaredMethods[i])) + //只对自己声明的方法进行增强 + return true; + } + return false; + } + }else { + String regex = super.getRegex(); + Pattern pattern = Pattern.compile(regex); + String compileMethodName = cls.getName() + "." + method.getName().toLowerCase(); + if(pattern.matcher(compileMethodName).matches()){ + return true; + }else + return false; + } + return false; } + public void before(Class cls,Method method,Object[] params) throws Throwable{ System.out.println("ni hao"); diff --git a/src/main/java/simple/xfj/framework/proxy/Proxy.java b/src/main/java/simple/xfj/framework/proxy/Proxy.java index bc596df..9d47a46 100644 --- a/src/main/java/simple/xfj/framework/proxy/Proxy.java +++ b/src/main/java/simple/xfj/framework/proxy/Proxy.java @@ -3,7 +3,17 @@ /** * Created by asus on 2017/4/20. */ -public interface Proxy { +public abstract class Proxy { - Object doProxy(ProxyChain proxyChain) throws Throwable; + private String regex; + + public abstract Object doProxy(ProxyChain proxyChain) throws Throwable; + + public String getRegex() { + return regex; + } + + public void setRegex(String regex) { + this.regex = regex; + } }