博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅说动态生成Class实现MVC
阅读量:6440 次
发布时间:2019-06-23

本文共 3899 字,大约阅读时间需要 12 分钟。

hot3.png

<h1>前言</h1> <p>java web的MVC,一个烂的不能再烂的一个话题了,可以说,现在市面上或者网上一搜,都有很多很优秀的MVC框架。那么这里为什么还要写一篇着相关的文章呢,在这介绍下本文的背景,之前帮一个朋友做个网站,由于本人只会java,所以就用java写了一个,但是由于资金有限,只能找一些便宜的jsp空间,那么这样随之而来的问题就是,这样的空间实在是给的东西有限,最主要的问题就是内存不够。所以就想,如果我不用任何框架,纯servlet编写,是否就能节约内存和提高执行效率,于是选择了直接采用servlet编写,但是这样确实带来很多维护和编程上的不便。于是就想能否写一个MVC框架,在程序执行之前按照规则自动生成各种代理类,那么在程序运行的时候就不需要什么反射,注入等等。既然目标已经确定,那么就按照这个思路继续往下走吧,就是如何按照规则自动生成我们想要的class。</p> <h1>Action规则制定</h1> <p>首先我们希望定义Action的规则,他的主要作用就是告诉程序,不同的请求是由哪些类和方法处理的。看看下面的代码: </p> <pre style="overflow: auto" class="brush:java;gutter:true;first-line:1;tab-size:4;toolbar:true;">代码1: @Action(&quot;/MockServlet&quot;) public class MockServletAction {

@UrlMapping(    value="/execute.action",    method="GET",    result="SUCCESS",    path="/servlet/test.jsp")public String execute() throws IOException {    return "SUCCESS";}

}</pre>

<p>这段代码很容易读懂,@Action注解告诉程序,所有以/MockServlet开头的请求由这个类处理,而@UrlMapping中的value告诉程序在/MockServlet之后又是&quot;/execute.action&quot;由execute()这个方法处理,并且必须是GET方式发送过来的请求;到到目前位置,这些注解有点Spring Mvc的味道了,接下来就是@UrlMapping的result和path属性了,其实他的意思就是当这个方法返回的是SUCCESS的时候采用&quot;/servlet/test.jsp&quot; 这个页面做图片的渲染。</p>

<p>接下来就是如何生成我们想要的代码了,首先让我们使用最原始的Servlet实现上面的功能,假设我们的Action没有任何注解,代码如下: </p>

<pre style="overflow: auto" class="brush:java;gutter:true;first-line:1;tab-size:4;toolbar:true;">代码2: public class MockServletAction { public String execute() throws IOException { return &quot;SUCCESS&quot;; } }</pre>

<p>我们同样想让这个Action去处理/MockServlet/execute.action这个GET请求,那么我们应该按照如下代码做:</p>

<pre style="overflow: auto" class="brush:java;gutter:true;first-line:1;tab-size:4;toolbar:true;">代码3: public class ActionServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String servletPath = req.getServletPath(); if(servletPath.equals(&quot;/MockServlet/execute.action&quot;)){ String result = new MockServletAction().execute(); if(result.equals(&quot;SUCCESS&quot;)){ req.getRequestDispatcher(&quot;/servlet/test.jsp&quot;).forward(request, response); } } } }</pre>

<p>通过上面就能够明白,我们希望有这么一个框架,它能够通过代码1中的注解的中所定义的请求转发规则来自定生成代码3。这样就既能够高效率的运行,减少系统运行时资源的损耗,同时也也能提高开发效率。 </p>

<p>我们也可以为事务做自动修改class,无非就是在方法前后加入事务启动和事务提交的代码;依赖注入的话就在构造方法中生成注入的代码等等. </p>

<h1>Class自动生成的策略</h1>

<p>有人也有疑问,就是我自动生成class,同样也是消耗资源的。没错不仅仅消耗资源,而且还消耗的非常多。但是这种消耗是一次性的,也就是说我程序运行开始就将class生成好,以后就直接使用这个class而无需重复生成。但是有的时候server的配置实在太烂,或者我就是个极端主义者,我就是希望server损耗的越少越好。那么为此这个就有以下两种策略供选择: </p>

<h2>1.运行时自动生成Class </h2>

<p>程序运行开始将所有需要的class自动生成或者将修改后的class替换成原有的class。当然这种方式的优点就是开发阶段快,但是弊端就是,我们无法在server中替换已经load的class,并且大多数的server提供商也不让你使用自定义系统级别的classloader,所以我们自动生成的class都将以反射的方式调用。 </p>

<h2>2.在开发阶段自动生成Class</h2>

<p>在开发阶段就自动生成class,然后打包到war包中,这样在server上运行的时候使用我们生成的class就和一般的方法调用没有任何区别,也就是这一点使得我们能够规避掉策略1中的弊端。原则上讲着一种方式在开发和打包这两个阶段中多了一个步骤,就是添加自动生成的class,但是由于项目采用MAVEN开发,我们能够编写一个maven插件,自动的执行自动生成类的打包。所以建议使用这种方式。 </p>

<h1>实现</h1>

<p>目前上述构想已经实现,项目名称为Wheel,而maven插件名称为wheel-maven-plugin。但是wheel所使用的依赖包asmsupport-0.3-SNAPSHOT,classgrep-1.2-SNAPSHOT都还没有release,还没有发布到maven,所以需要手动maven install到本地的maven仓库。各个包编译打包顺序如下: </p>

<ul> <ol>asmsupport执行maven clean install</ol>

<ol>classgrep执行maven clean install</ol>

<ol>wheel执行maven clean install</ol>

<ol>wheel-maven-plugin执行maven clean install</ol> </ul>

<p>这里也有一个简单是实例WheelSampleApp, 里面展示了大部分的功能,如AOP,注入等等。</p>

<p>以上涉及到的项目的源码地址:</p>

<ul> <ol><b>asmsupport:</b>http://code.taobao.org/svn/asmsupport/trunk</ol>

<ol><b>classgrep:</b>http://code.taobao.org/svn/classgrep/trunk</ol>

<ol><b>wheel:</b>http://code.taobao.org/svn/wheel/trunk</ol>

<ol><b>wheel-maven-plugin:</b>http://code.taobao.org/svn/wheel-maven-plugin/trunk</ol>

<ol><b>WheelSampleApp:</b>http://code.taobao.org/svn/WheelSampleApp/trunk</ol> </ul>

<p>Wheel和wheel-maven-plugin正在酝酿发布第一个版本,而calssgrep-1.1和asmsupport-0.2都已经发布,只是wheel所依赖的classgrep-1.2和asmsupport-0.3 这两个新版本还为发布,后续也将补全新功能和bug陆续发布。 </p>

转载于:https://my.oschina.net/wensiqun/blog/169494

你可能感兴趣的文章
彻底理解javascript中的this指针
查看>>
SAS去空格
查看>>
Spring Cloud构建微服务架构(二)服务消费者
查看>>
这些老外的开源技术养活了一票国产软件
查看>>
Maven实战(六)--- dependencies与dependencyManagement的区别
查看>>
创业者应该有的5个正常心态(转)
查看>>
php模式设计之 注册树模式
查看>>
【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面
查看>>
_ENV和_G
查看>>
别做操之过急的”无效将军”,做实实在在的”日拱一卒” 纵使一年不将军,不可一日不拱卒...
查看>>
Oracle Grid Infrastructure: Understanding Split-Brain Node Eviction (文档 ID 1546004.1)
查看>>
Linux改变进程优先级的nice命令
查看>>
**16.app后端如何保证通讯安全--url签名
查看>>
win32窗口机制之CreateWindow
查看>>
C/C++ 一段代码区分数组指针|指针数组|函数指针|函数指针数组
查看>>
awakeFromNib小总结
查看>>
java知识大全积累篇
查看>>
善于总结所做所学的内容
查看>>
Lua-简洁、轻量、可扩展的脚本语言
查看>>
org.hibernate.MappingException: entity class not found hbm可以解析,但是实体类不能解析...
查看>>