在前面的v1版,因为咱们临时起意,存在很多问题,我从新设计框架v2版chen(重名问题更名为chen)。 java
原理图以下: mysql
先说下chen框架的功能: web
设计思路以下: sql
视图实现: 数据库
控制器实现: restful
模型实现: mvc
Aop实现: oracle
Ioc实现: 框架
仓储实现: 异步
总体处理流程以下:
用户在页面发起了一个action的请求,前置控制器截获了这个请求,验证以后,将请求地址转化为路由,根据请求类型同步或异步,生成执行环境(包括:Request、路由、action实例、方法、参数等),将执行环境放入handler中(同步或异步请求,有不一样的handler,也能够自定义扩展),handler依次执行:初始化、执行、渲染视图、销毁资源4个步骤处理请求,在执行时先执行aop before,而后执行action,action中调用的model,从ioc容器得到,model使用dao工具类,操做数据库。再执行aop after。渲染视图是根据action返回结果,渲染特定视图或保存数据。最后销毁资源。
代码
前置控制器FrontControl.java
package chen; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.AsyncContext; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import chen.aop.Binder; import chen.ioc.Chen; import chen.util.ContextUtil; @WebFilter(urlPatterns = { "/ty/*" }, asyncSupported = true) public class FrontControl implements Filter{ private AtomicBoolean initialized = new AtomicBoolean(); private ServletContext servletContext; @Override public void init(final FilterConfig config) throws ServletException{ try { if (initialized.compareAndSet(false, true)) { long time1 = System.currentTimeMillis(); this.servletContext = config.getServletContext(); Scaner.run(); Binder.load(); System.out.println(">>> chen 已经启动,用时"+(System.currentTimeMillis()-time1)/1000+"秒"); } } catch (Exception e) { throw new ChenException(" >>> chen 启动失败",e); } } @Override public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws ServletException, IOException{ HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; String[] routes = valid(req); if(routes == null){ chain.doFilter(request, response); return; } try { long time1 = System.currentTimeMillis(); Context context = null; IHandler handler = null; if(routes[0].endsWith("Async")){ AsyncContext async = req.startAsync(); async.setTimeout(30*1000); context = new Context(routes,Scaner.getCls(),Binder.getAop(routes),req,res,servletContext,async); async.start(new AsynHandler(context)); }else{ context = new Context(routes,Scaner.getCls(),Binder.getAop(routes),req,res,servletContext); handler = new ChenHandler(context); handler.init(); } System.out.println(">>> chen 处理路由/"+routes[0]+"/"+routes[1]+"/完成,用时"+(System.currentTimeMillis()-time1)/1000+"秒"); } catch (Exception e) { throw new ChenException(" >>> chen 处理路由/"+routes[0]+"/"+routes[1]+"/失败",e); } } private String[] valid(HttpServletRequest req){ String uri = req.getRequestURI(); String path = req.getContextPath(); if (path != null){ uri = uri.substring(path.length()); }else{ return null; } String[] routes = uri.substring(uri.indexOf("/ty/")+4).split("/"); if(routes == null || routes.length<2){ return null; } return routes; } @Override public void destroy() { } }
执行环境Context.java
package chen; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Map; import javax.servlet.AsyncContext; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import chen.aop.Aop; import chen.ioc.Chen; import chen.util.ChenMap; public class Context { public final Map<String,String> cls; public final Object[] aops; public final String[] routes; public final HttpServletRequest reqs; public final HttpServletResponse resp; public final ServletContext servletContext; public final AsyncContext async; public final Object instance; public final Method method; public final Map<String,Object> args; public Context(String[] routes,Map<String,String> cls,String[] aops,HttpServletRequest reqs,HttpServletResponse resp,ServletContext servletContext) throws ClassNotFoundException, SecurityException, NoSuchMethodException{ this.cls = cls; this.aops = this.converter(aops); this.routes = routes; this.reqs = reqs; this.resp = resp; this.servletContext = servletContext; this.instance = Chen.container.get(Class.forName(this.cls.get(this.routes[0]+"Action"))); this.method = this.instance.getClass().getMethod(routes[1],Map.class); this.args = this.converter(this.reqs.getParameterMap()); this.async = null; } public Context(String[] routes,Map<String,String> cls,String[] aops,HttpServletRequest reqs,HttpServletResponse resp,ServletContext servletContext,AsyncContext async) throws ClassNotFoundException, SecurityException, NoSuchMethodException{ this.cls = cls; this.aops = this.converter(aops); this.routes = routes; this.reqs = reqs; this.resp = resp; this.servletContext = servletContext; this.instance = Chen.container.get(Class.forName(this.cls.get(this.routes[0]+"Action"))); this.method = this.instance.getClass().getMethod(routes[1],Map.class); this.args = this.converter(this.reqs.getParameterMap()); this.async = async; } private Object[] converter(String[] aops) throws ClassNotFoundException{ Object[] aopIns = null; if(aops !=null && aops.length>0){ aopIns = new Object[aops.length]; for(int a=0;a<aops.length;a++){ aopIns[a] = Chen.container.get(Class.forName(aops[a])); } } return aopIns; } private Map<String,Object> converter(Map<String,String[]> args){ if(args == null){ return null; } Map<String, Object> params = new ChenMap(); for(String key : args.keySet()){ params.put(key, Arrays.toString(args.get(key)).replaceAll("[\\[\\]\\s,]", "")); } return params; } }