当前位置: 首页 > news >正文

江苏网站集约化建设我有多个单页网站需要备案吗

江苏网站集约化建设,我有多个单页网站需要备案吗,官方网站建设审批手续,开山云匠网当从编译到部署再到测试的开发周期花费太长时间时#xff0c;人们希望能够及时替换正在运行的代码#xff0c;而无需重新启动应用程序服务器并等待部署完成。 在这种情况下#xff0c;像JRebel这样的商业解决方案或像Grails这样的开源框架就可以提供帮助。 JVM不支持在运行… 当从编译到部署再到测试的开发周期花费太长时间时人们希望能够及时替换正在运行的代码而无需重新启动应用程序服务器并等待部署完成。 在这种情况下像JRebel这样的商业解决方案或像Grails这样的开源框架就可以提供帮助。 JVM不支持在运行时替换代码例如您可以使用Class.forName()动态加载类。 基本上您有以下选择 HotSwapJava 1.4引入的技术可让您在调试器会话中重新定义类。 这种方法非常有限因为它仅允许您更改方法的主体而不能添加新的方法或类。 OSGi这项技术允许您定义包。 在运行时可用此软件包的较新版本替换该软件包。 一次性类加载器通过在模块的所有类上包装单独的类加载器可以在模块的新版本可用时丢弃类加载器并进行替换。 使用Java代理检测类Java代理可以在定义类之前对它们进行检测。 这样它可以将代码注入到已加载的类中该类将此类与类文件的一个版本连接起来。 一旦有新版本可用将执行新代码。 Grails所采用的技术称为“ 弹簧加载” 它使用“ Java代理”方法来处理从文件系统而不是从jar文件加载的类。 但是这在后台如何工作 为了了解弹簧负载我们建立了一个小样本项目使我们可以更详细地研究该技术。 该项目仅包含两个类 Main类调用ToBeChanged类的print()方法并休眠一会儿 public static void main(String[] args) throws InterruptedException {while (true) {ToBeChanged toBeChanged new ToBeChanged();toBeChanged.print();Thread.sleep(500);} } print()方法仅打印出一个版本以便我们可以看到它已更改。 此外我们还打印出堆栈跟踪以查看其随时间的变化 public void print() {System.out.println(V1);StackTraceElement[] stackTrace Thread.currentThread().getStackTrace();for (StackTraceElement element : stackTrace) {System.out.println(\t element.getClassName() . element.getMethodName() : element.getLineNumber());} } 启动应用程序时我们必须使用选项javaagent提供包含Java Agent的jar文件。 当弹簧加载以验证者不喜欢的方式修改字节码时我们必须通过将选项noverify传递给JVM来禁用字节码的验证。 最后我们使用cp传递包含类文件的文件夹并告诉JVM包含main()方法的类 java -javaagent:springloaded-1.2.4.BUILD-SNAPSHOT.jar -noverify -cp target/classes com.martinsdeveloperworld.springloaded.Main 将ToBeChanged类的版本从V1更新到V2并使用mvn package重建项目后我们看到以下输出 ... V1java.lang.Thread.getStackTrace:-1com.martinsdeveloperworld.springloaded.ToBeChanged.print:7com.martinsdeveloperworld.springloaded.Main.main:8 V2java.lang.Thread.getStackTrace:-1com.martinsdeveloperworld.springloaded.ToBeChanged$$EPBF0gVl.print:7com.martinsdeveloperworld.springloaded.ToBeChanged$$DPBF0gVl.print:-1com.martinsdeveloperworld.springloaded.ToBeChanged.print:-1com.martinsdeveloperworld.springloaded.Main.main:8 ... 版本V1的stacktrace看起来像我们期望的那样。 从Main.main()方法ToBeChanged.print()被调用。 对于版本V2这是不同的。 在这里方法ToBeChanged.print现在调用方法ToBeChanged$$DPBF0gVl.print() 。 还请注意调用ToBeChanged.print()的行号已从8更改为-1表示该行未知。 新的行号-1强烈表明Java代理已经以一种允许它调用新方法而不是执行旧代码的方式来检测方法ToBeChanged.print() 。 为了证明这一假设我在spring-loaded的代码中添加了一些日志记录语句并添加了一个功能可将每个插入的文件转储到本地硬盘驱动器中。 这样我们可以检查ToBeChanged.print()后方法ToBeChanged.print()外观 0 getstatic #16 com/martinsdeveloperworld/springloaded/ToBeChanged.r$type3 ldc #72 05 invokevirtual #85 org/springsource/loaded/ReloadableType.changed8 dup9 ifeq 42 (33)12 iconst_113 if_icmpeq 26 (13)16 new #87 java/lang/NoSuchMethodError19 dup20 ldc #89 com.martinsdeveloperworld.springloaded.ToBeChanged.print()V22 invokespecial #92 java/lang/NoSuchMethodError.init25 athrow26 getstatic #16 com/martinsdeveloperworld/springloaded/ToBeChanged.r$type29 invokevirtual #56 org/springsource/loaded/ReloadableType.fetchLatest32 checkcast #58 com/martinsdeveloperworld/springloaded/ToBeChanged__I35 aload_036 invokeinterface #94 com/martinsdeveloperworld/springloaded/ToBeChanged__I.print count 241 return42 pop43 getstatic #100 java/lang/System.out46 ldc #102 V148 invokevirtual #107 java/io/PrintStream.println51 invokestatic #113 java/lang/Thread.currentThread54 invokevirtual #117 java/lang/Thread.getStackTrace57 astore_1 ... 152 return getstatic操作码检索新字段r$type的值并将其压入堆栈操作码ldc 。 然后调用方法ReloadableType.changed()来调用之前已推入堆栈的对象引用。 顾名思义方法ReloadableType.changed()检查此类型的新版本是否存在。 如果方法未更改则返回0如果方法已更改则返回1。 如果返回值为零即方法未更改则以下操作码ifeq跳至第42行。 从第42行开始我们看到了原来的实现我在这里将其缩短了一点。 如果值为1则if_icmpeq指令跳至第26行在此再次读取静态字段r$type 。 此引用用于在其上调用方法ReloadableType.fetchLatest() 。 下面的checkcast指令验证返回的引用的类型为ToBeChanged__I 。 在这里我们第一次偶然发现了这种弹簧接口为每种类型生成的人工接口。 它反映了原始类在进行检测时所具有的方法。 两行之后此接口用于在ReloadableType.fetchLatest()返回的引用上调用方法print() ReloadableType.fetchLatest() 。 该引用不是对该类的新版本的引用而是对所谓的调度程序的引用。 调度程序实现ToBeChanged__I接口并通过以下指令实现方法print() 0 aload_1 1 invokestatic #21 com/martinsdeveloperworld/springloaded/ToBeChanged$$EPBF0gVl.print 4 return 动态生成的类ToBeChanged$$EPBF0gVl是所谓的执行程序体现了该类型的新版本。 对于每个新版本都会创建一个新的调度程序和执行程序只有接口保持不变。 一旦有新版本可用则在新调度程序上调用接口方法并且在最简单的情况下该接口方法将转发至执行程序中包含的代码的新版本。 不能直接在执行器上调用接口方法的原因是弹簧加载还可以处理在新版本的类中添加方法的情况。 由于此方法在旧版本中不存在因此将通用方法__execute()添加到接口和调度程序。 然后此动态方法可以将调用调度到新方法如从生成的调度程序中获取的以下指令集中所示 0 aload_31 ldc #25 newMethod()V3 invokevirtual #31 java/lang/String.equals6 ifeq 18 (12)9 aload_2 10 checkcast #33 com/martinsdeveloperworld/springloaded/ToBeChanged 13 invokestatic #36 com/martinsdeveloperworld/springloaded/ToBeChanged$$EPBFaboY.newMethod 16 aconst_null 17 areturn 18 aload_3 ... 68 areturn 在这种情况下我向类ToBeChanged添加了一个名为newMethod()的新方法。 __execute()方法的开头比较调用的描述符是否与新方法匹配。 在这种情况下它将调用转发给新的执行者。 为了使此工作正常进行必须将新方法的所有调用都重写为__execute()方法。 这也可以通过对原始类的检测来完成并且也可以进行反射。 结论 Spring展示了在运行时可以用较新版本“替换”一个类的可能性。 为了实现这一点利用了一系列Java技术例如Java Agent和字节码检测。 通过仔细研究实现可以大致了解有关JVM和Java的许多知识。 翻译自: https://www.javacodegeeks.com/2015/05/updating-code-at-runtime-spring-loaded-demystified.html
http://www.zqtcl.cn/news/168045/

相关文章:

  • 做海报有什么素材网站知乎什么样的蓝色做网站做好看
  • 餐饮网站建设网站wordpress优酷视频插件下载
  • 什么网站做广告效果好wordpress中文cms
  • seo与网站优化广州洲聚网站开发
  • 建一个自己用的网站要多少钱北京网站建设价格天
  • 免费做婚礼邀请函的网站如何设定旅游网站seo核心关键词
  • 网上做问卷调查赚钱哪些网站好全flash网站制作
  • 个人网站备案核验单填写wordpress登录安全插件下载
  • 拖拽做网站cms系统设计
  • 村建站什么部门网站建设步骤图
  • 移动端网站建设的意义中工信融网站建设
  • 网站设计宽屏尺寸盐城网站建设渠道合作
  • 网站所有者查询hexo做网站
  • 杭州专业网站设计策划大数据网站建设和
  • 建一个自己的网站需要多少钱泰州网站快速排名优化
  • 企业网站的建设企业湖南网络推广
  • 山西省建设厅投诉网站郴州新网交友手机版
  • 营销网站建设是什么flash个人网站欣赏
  • 网站建设最简单的教程视频教程建设厅注册中心网站首页
  • 免费做网站凡科wordpress 分享到微信 插件
  • 购物网站项目建设内容有啥网站是专做时尚穿搭
  • 网上下载的网站模板怎么用wordpress 注册密码
  • 网站建设免费国外撤销网站备案申请书
  • 佛山做网站那家好网站建设公司如何盈利
  • 傻瓜建网站设计感网站
  • 北京网站优化软件陕西省建筑信息平台
  • 广州越秀建网站济南房产网新开楼盘
  • 线上咨询预约网站建设方案保定外贸网站制作
  • 网站流量如何增加提高工作效率的措施
  • 龙湖镇华南城网站建设.net 网站开发书籍