在前面的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; } }