JavaWorld一篇题为 Add dynamic code to your application 的文章介绍了如何使用动态代理技术使普通的java源代码具有像jsp一样的动态编译效果,十分有趣。
  使用过jsp技术的程序员都知道,应用部署以后,我们是可以直接修改jsp源文件的。当客户请求这个被修改过的jsp文件时,web容器会自动监测出该jsp文件已经被更新,因此重新编译该jsp文件,向客户返回最新的信息。但是,对于一般的java源文件,如果我们仅仅修改源文件,而不重新编译部署的话,web容器是不会处理的。
   那我们可不可以让普通的java源文件也具有jsp一样的效果呢,也就是说,程序在运行过程中,我们一旦修改某个类的源文件,程序会自动监测出来,并重新编译该文件,同时进行重新连接,动态更新。答案是肯定的,而且方法并不复杂。主要思想是当执行一个接口的操作时,我们使用动态代理技术将其拦截,然后监测实现该接口的类的源文件是否已经更新,如果没有更新,则把方法交给相应的对象的方法执行,否则,我们重新编译该类的源文件,同时重新加载该类,然后,我们就可以通过该类获得最新的对象以执行相应的操作了。
    系统的总体架构是是一个Dynamic Proxy,而实现的重点是捕捉到接口方法时在调用invoke的时候如何动态编译和重新加载。编译我们可以使用java提供的com.sun.tools.javac.Main.compile方法(要将jdk lib目录下的tool.jar加入到classpath中),通过该方法我们可以将指定的源文件进行编译并将相应的class文件放置到指定的目录中。
     为了能够进行重新连接,我们必须要把原来已经被加载的类卸载,否则我们是不能够将最新的类加载到jvm中去的。但是,我们卸载时却不能指定把classloader装载的类中的某一个类卸载掉,因此,我们只好重新生成一个classloader,通过它来重新加载我们新编译好的class文件。在这里,URLClassLoader是一个很好的选择。

updated(2009-3-16):

JVM中的Class只有满足以下三个条件,才能被GC回收,也就是该Class被卸载(unload):

- 该类所有的实例都已经被GC,也就是JVM中不存在该Class的任何实例。
   - 加载该类的ClassLoader已经被GC。
   - 该类的java.lang.Class 对象没有在任何地方被引用,如不能在任何地方通过反射访问该类的方法.

java动态代码的实现以及Class的卸载 (转至http://dustin.iteye.com/blog/46393)的更多相关文章

  1. Java动态代码模式

    java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委 ...

  2. JAVA,模拟HTTP登录(略有修改) ----转载自http://zhoujingxian.iteye.com/blog/439738

    /* * 网上的一个模拟登录或者模拟注册程序 * 2013-8-5 */ package Socket_Http; import java.io.BufferedReader; import java ...

  3. 【剑指offer】Java版代码(完整版)

    原文地址:https://blog.csdn.net/baiye_xing/article/details/78428561 一.引言 <剑指offer>可谓是程序猿面试的神书了,在面试中 ...

  4. (转载)JAVA动态编译--字节代码的操纵

    在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...

  5. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  6. 如何实现在已有代码之后添加逻辑之java动态代理

    在上篇博客中讨论到java的静态代理, 就是通过组合的方法,前提是委托类需要实现一个接口,代理类也实现这个这个 接口,从何组合两个类,让代理类给委托类添加功能! 知道java的静态代理,我们又遇到一个 ...

  7. java动态代理实现与原理详细分析(代码层面解释了AOP的实现)

    关于Java中的动态代理,我们首先需要了解的是一种常用的设计模式--代理模式,而对于代理,根据创建代理类的时间点,又可以分为静态代理和动态代理. 一.代理模式    代理模式是常用的java设计模式, ...

  8. java动态编译 (java在线执行代码后端实现原理)(二)

    在上一篇java动态编译 (java在线执行代码后端实现原理(一))文章中实现了 字符串编译成字节码,然后通过反射来运行代码的demo.这一篇文章提供一个如何防止死循环的代码占用cpu的问题. 思路: ...

  9. java动态编译 (java在线执行代码后端实现原理)

    需求:要实现一个web网页中输入java代码,然后能知道编译结果以及执行结果 类似于菜鸟java在线工具的效果:https://c.runoob.com/compile/10 刚开始从什么概念都没有到 ...

随机推荐

  1. mysql-5.7中innodb_buffer_pool页面淘汰算法

    一. 什么是innodb_buffer_pool: innodb_buffer_pool是一块内存区域,innodb用它来缓存数据,索引,undo,change buffer ... : 这块区域又被 ...

  2. Python中的break和continue的使用方法

    一.continue的使用方法(结束当前的循序,进行下一个数的循环) # *************************************************************** ...

  3. Servlet和Android网络交互基础(3)

    在上一章中採用了最简单的创建service端代码方式,但在实际开发中一般都会採用比較成熟的框架.以下是完整的maven+spring mvc 创建service的方式 下载安装Eclipse 和jdk ...

  4. RhinoMock初探

    官方wiki:http://www.ayende.com/wiki/Rhino+Mocks.ashx ========================================= 接口Mock: ...

  5. [na]windows2008-AD域的安装

    AD域的安装 初始化设置,改计算机名字dcserver,改静态ip,改dns指向自己. dcpromo,执行后自动装了dns 安装完后检查 1.本地用户没了 2,dns指向自己 3,dns记录是否齐全 ...

  6. C# 使用Nlog记录日志到数据库

    [摘要]Nlog是一个很不错的.NET日志记录组件,它可以将日志输出到控件台,保存到文本,也可以很方便的记录到数据库中.本文为你介绍C# 使用Nlog记录日志到数据库. Nlog是一个很不错的.NET ...

  7. I/O Completion Ports

    http://weblogs.asp.net/kennykerr/parallel-programming-with-c-part-4-i-o-completion-ports http://webl ...

  8. 每日英语:Genetic Manipulation Extends Life of Mice 20%

    By reducing the activity of one type of gene, scientists said they increased the average life span o ...

  9. 李洪强iOS之集成极光推送一iOS SDK概述

    李洪强iOS之集成极光推送一iOS SDK概述 JPush iOS 从上图可以看出,JPush iOS Push 包括 2 个部分,APNs 推送(代理),与 JPush 应用内消息. 红色部分是 A ...

  10. vue轮播图插件vue-awesome-swiper的使用与组件化

    不管是APP还是移动端网页开发,轮播图在大部分项目当中都是存在的,这时候如果用vue开发项目,选择一款好的插件并且封装好是很重要的 1. 推荐使用vue-awesome-swiper 安装:cnpm ...