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

简述营销型网站开发流程功能类网站

简述营销型网站开发流程,功能类网站,住房和城乡建设部政务服务门户,新站整站快速排名热加载#xff1a;在不停止程序运行的情况下#xff0c;对类#xff08;对象#xff09;的动态替换。Java ClassLoader 简述Java中的类从被加载到内存中到卸载出内存为止#xff0c;一共经历了七个阶段#xff1a;加载、验证、准备、解析、初始化、使用、卸载。接下来我们… 热加载在不停止程序运行的情况下对类对象的动态替换。Java ClassLoader 简述Java中的类从被加载到内存中到卸载出内存为止一共经历了七个阶段加载、验证、准备、解析、初始化、使用、卸载。接下来我们重点讲解加载和初始化这两步加载在加载的阶段虚拟机需要完成以下三件事通过一个类的全限定名来获取定义此类的二进制字节流将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的java.lang.Class对象作为方法区这个类的各种数据的访问入口。这三步都是通过类加载器来实现的。而官方定义的Java类加载器有BootstrapClassLoader、ExtClassLoader、AppClassLoader。这三个类加载器分别负责加载不同路径的类的加载。并形成一个父子结构。类加载器名称负责加载目录BootstrapClassLoader处于类加载器层次结构的最高层负责 sun.boot.class.path 路径下类的加载默认为 jre/lib 目录下的核心 API 或 -Xbootclasspath 选项指定的 jar 包ExtClassLoader加载路径为 java.ext.dirs默认为 jre/lib/ext 目录或者 -Djava.ext.dirs 指定目录下的 jar 包加载AppClassLoader加载路径为 java.class.path默认为环境变量 CLASSPATH 中设定的值。也可以通过 -classpath 选型进行指定默认情况下例如我们使用关键字new或者Class.forName都是通过AppClassLoader类加载器来加载的正因为是此父子结构所以默认情况下如果要加载一个类会优先将此类交给其父类进行加载直到顶层的BootstrapClassLoader也没有如果父类都没有那么才会将此类交给子类加载。这就是类加载器的双亲委派规则。初始化当我们要使用一个类的执行方法或者属性时类必须是加载到内存中并且完成初始化的。那么类是什么时候被初始化的呢有以下几种情况使用new关键字实例化对象的时候、读取或者设置一个类的静态字段、以及调用一个类的静态方法。使用java.lang.reflect包的方法对类进行反射调用时如果类没有进行初始化那么先进行初始化。初始化一个类的时候如果发现其父类没有进行初始化则先触发父类的初始化。当虚拟机启动时用户需要制定一个执行的主类(包含main()方法的那个类)虚拟机会先初始化这个主类。如何实现热加载在上面我们知道了在默认情况下类加载器是遵循双亲委派规则的。所以我们要实现热加载那么我们需要加载的那些类就不能交给系统加载器来完成。所以我们要自定义类加载器来写我们自己的规则。实现自己的类加载器要想实现自己的类加载器只需要继承ClassLoader类即可。而我们要打破双亲委派规则那么我们就必须要重写loadClass方法因为默认情况下loadClass方法是遵循双亲委派的规则的。public class CustomClassLoader extends ClassLoader{private static final String CLASS_FILE_SUFFIX .class;//AppClassLoader的父类加载器private ClassLoader extClassLoader;public CustomClassLoader(){ClassLoader j String.class.getClassLoader();if (j null) {j getSystemClassLoader();while (j.getParent() ! null) {j j.getParent();}}this.extClassLoader j ;}protected Class? loadClass(String name, boolean resolve){Class cls null;cls findLoadedClass(name);if (cls ! null){return cls;}//获取ExtClassLoaderClassLoader extClassLoader getExtClassLoader() ;//确保自定义的类不会覆盖Java的核心类try {cls extClassLoader.loadClass(name);if (cls ! null){return cls;}}catch (ClassNotFoundException e ){}cls findClass(name);return cls;}Overridepublic Class? findClass(String name) {byte[] bt loadClassData(name);return defineClass(name, bt, 0, bt.length);}private byte[] loadClassData(String className) {// 读取Class文件呢InputStream is getClass().getClassLoader().getResourceAsStream(className.replace(., /)CLASS_FILE_SUFFIX);ByteArrayOutputStream byteSt new ByteArrayOutputStream();// 写入byteStreamint len 0;try {while((lenis.read())!-1){byteSt.write(len);}} catch (IOException e) {e.printStackTrace();}// 转换为数组return byteSt.toByteArray();}public ClassLoader getExtClassLoader(){return extClassLoader;} } 为什么要先获取ExtClassLoader类加载器呢其实这里是借鉴了Tomcat里面的设计是为了避免我们自定义的类加载器覆盖了一些核心类。例如java.lang.Object。为什么是获取ExtClassLoader类加载器而不是获取AppClassLoader呢这是因为如果我们获取了AppClassLoader进行加载那么不还是双亲委派的规则了吗监控class文件这里我们使用ScheduledThreadPoolExecutor来进行周期性的监控文件是否修改。在程序启动的时候记录文件的最后修改时间。随后周期性的查看文件的最后修改时间是否改动。如果改动了那么就重新生成类加载器进行替换。这样新的文件就被加载进内存中了。首先我们建立一个需要监控的文件public class Test {public void test(){System.out.println(Hello World! Version one);} } 我们通过在程序运行时修改版本号来动态的输出版本号。接下来我们建立周期性执行的任务类。public class WatchDog implements Runnable{private MapString,FileDefine fileDefineMap;public WatchDog(MapString,FileDefine fileDefineMap){this.fileDefineMap fileDefineMap;}Overridepublic void run() {File file new File(FileDefine.WATCH_PACKAGE);File[] files file.listFiles();for (File watchFile : files){long newTime watchFile.lastModified();FileDefine fileDefine fileDefineMap.get(watchFile.getName());long oldTime fileDefine.getLastDefine();//如果文件被修改了,那么重新生成累加载器加载新文件if (newTime!oldTime){fileDefine.setLastDefine(newTime);loadMyClass();}}}public void loadMyClass(){try {CustomClassLoader customClassLoader new CustomClassLoader();Class? cls customClassLoader.loadClass(com.example.watchfile.Test,false);Object test cls.newInstance();Method method cls.getMethod(test);method.invoke(test);}catch (Exception e){System.out.println(e);}} } 可以看到在上面的演示图中我们简单的实现了热加载的功能。优化在上面的方法调用中我们是使用了getMethod()方法来调用的。此时或许会有疑问为什么不直接将newInstance()强转为Test类呢如果我们使用了强转的话代码会变成这样Test test (Test) cls.newInstance()。但是在运行的时候会抛ClassCastException异常。这是为什么呢因为在Java中确定两个类是否相等除了看他们两个类文件是否相同以外还会看他们的类加载器是否相同。所以即使是同一个类文件如果是两个不同的类加载器来加载的那么它们的类型就是不同的。WatchDog类是由我们new出来的。所以默认是AppClassLoader来加载的。所以test变量的声明类型是WatchDog方法中的一个属性所以也是由AppClassLoader来加载的。因此两个类不相同。该如何解决呢问题就出在了号双方的类不一样那么我们给它搞成一样不就行了吗怎么搞答案就是接口。默认情况下如果我们实现了一个接口那么此接口一般都是以子类的加载器为主的。意思就是如果没有特殊要求的话例如A implements B 如果A的加载器是自定义的。那么B接口的加载器也是和子类是一样的。所以我们要将接口的类加载器搞成是AppClassLoader来加载。所以自定义加载器中加入这一句if (com.example.watchfile.ITest.equals(name)){try {cls getSystemClassLoader().loadClass(name);} catch (ClassNotFoundException e) {}return cls; } 建立接口public interface ITest {void test(); } 这样我们就能愉快的调用了。直接调用其方法。不会抛异常因为号双方的类是一样的。CustomClassLoader customClassLoader new CustomClassLoader(); Class? cls customClassLoader.loadClass(com.example.watchfile.Test,false); ITest test (ITest) cls.newInstance(); test.test(); 参考文章www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/index.htmlJava虚拟机作者不学无数的程序员链接www.jianshu.com/p/d8fa14802b7a
http://www.zqtcl.cn/news/366314/

相关文章:

  • 网站开发怎么报价推广普通话手抄报模板可打印
  • 好的平面网站模板企业网站建设浩森宇特
  • 做网站通过什么赚钱吗公司建设网站的费用
  • 如何做建筑一体化的网站视频网站开发应用到哪些技术
  • 巴中微信网站建设竞价托管一般多少钱
  • 彩票网站开发 违法股票网站排名哪个好
  • 宝格丽网站建设哈尔滨网站建设王道下拉強
  • 烟台网站建设的公司世界500强企业排名2021
  • 网络营销做得比较成功的案例吴中seo网站优化软件
  • 怎么设立网站美区下载的app怎么更新
  • 建立网站ppt做酒店网站所用到的算法
  • 上海网站建设的价格低太仓做网站的公司
  • 怎样登录建设互联网站怎么做中英文网站
  • 云网站7china中小企业网站建设好么
  • 美丽南方官网网站建设国际新闻最新消息今天摘抄
  • 牛商网营销型网站多少钱江门营销型网站建设多少钱
  • 小榄公司网站建设网站交互做的比较好的
  • 深圳定制网站建设怎么改版网站
  • 免费学软件的自学网站江阴建设局网站
  • 网站做多久苍南县网站集约化建设
  • 深圳电子烟网站建设罗湖建设公司网站建设
  • 酒店 深圳 网站建设新项目首码对接平台
  • 岳阳市住房和城乡建设局网站上海专业网站建设网
  • 营销型网站建设设定包括哪些方面网站建设后的心得
  • 建立网站来网上销售的英文潢川城乡建设局网站
  • 仿站建站教程网站怎么接广告
  • 免费下载代码项目的网站长春网站建设找新生科技
  • 博兴县建设局网站做网站要用什么服务器吗
  • 成都中小企业网站建设公司怎么挑选网站建设公司
  • 万源网站建设在ppt里面做网站链接