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

门户网站是以什么为主上海协会网站建设

门户网站是以什么为主,上海协会网站建设,苏州市住房和城乡建设局官方网站,东莞seo建站怎么投放文章目录 类的加载过程加载阶段链接阶段初始化 类的加载器测试代码中获取对应的加载器获取加载器加载的路径不同类对应的加载器自定义加载器自定义加载器的方式 获取类的加载器的方式双亲委派机制双亲委派机制的好处 Java 的 SPI 机制1. 接口定义2. 具体实现3. 配置 META-INF/s… 文章目录 类的加载过程加载阶段链接阶段初始化 类的加载器测试代码中获取对应的加载器获取加载器加载的路径不同类对应的加载器自定义加载器自定义加载器的方式 获取类的加载器的方式双亲委派机制双亲委派机制的好处 Java 的 SPI 机制1. 接口定义2. 具体实现3. 配置 META-INF/services 文件4. 接口的使用 类的加载过程 类的加载过程分为3个阶段 加载阶段链接阶段初始化阶段 类的加载器只负责加载 .class 文件至于能不能执行是执行引擎决定的。 加载阶段 通过类的全限定名获取此类的二进制流将此类的二进制流中静态储存结构存储在运行时数据区的方法区元空间 7.0 或永久代 7.0在内存中生成一个 java.lang.Class 的对象作为方法区在这个类的各种数据的访问入口 虽然一般情况下JVM 加载的是 .class 文件其实只要是符合 JVM 的字节码都可以进行加载。比如.jar 包中的文件动态代理生成的字节码可在运行时动态生成还比如加密的 .class 文件通过 JVM 解密后加载可有效防止反编译。 链接阶段 验证Verify 每个 .class 文件都有一个特殊的开头用以表示该文件是 JVM 支持的 .class 文件。验证的目的在于确保被加载的类的正确性。主要验证方式文件格式验证、元数据验证、字节码验证、符号引用验证 准备Prepare 为类变量分配内存并且设置类变量的初始值注意初始值为 0。如private static int a 10;这个时候 a 的值为 0特殊的如果变量用 final 修饰如private final static int b 10;这个时候 b 的值为 10因为 final 修饰表示 b 为常量在编译期初始化。此时成员变量不会初始化static 修饰的 a 为类变量类变量在类加载的时候初始化如 private int c 10c 是成员变量是和对象一起被分配到 Java 堆中的。 解析Resolve 将常量池内的符号引用转换为直接引用的过程解析主要针对类或接口、字段、各种方法类方法、接口方法等 初始化 初始化静态变量和静态块此对应执行类构造器方法clinit()此方法的指令按源文件中的顺序执行。如果没有相关静态变量或静态块可能不会有 clinit() 方法。成员变量和局部变量对应 JVM 下的 init()方法。 类的加载器 引导类启动类加载器Bootstrap ClassLoder负责加载 Java 的核心类库JAVA_HOME/jre/lib/rt.jar、resource.jar、sun、java、javax 包开头的类 使用 C/C 实现的并不继承自 ClassLoader 类。自定义类加载器直接或间接继承自 ClassLoader 类的类加载器。是由 Java 实现的。 扩展类加载器sun.misc.Launcher$ExtClassLoaderExtClassLoader 是 Launcher 对象的内部类其父类加载器为引导类加载器其加载的是系统属性 java.ext.dirs 所指定的目录 或者 从 JAVA_HOME/jre/lib/ext 目录下加载类。我们自定义的 jar 包放在此目录也会被加载系统类应用程序类加载器sun.misc.Launcher$AppClassLoader其父类加载器为扩展类加载器负责加载环境变量 classpath 或 系统属性 java.class.path 所指定的目录下的类。其他自定义的类加载器 注意他们不是继承关系我们可以称他们为扩展关系。 测试代码中获取对应的加载器 public static void main(String[] args) {ClassLoader app ClassLoader.getSystemClassLoader();System.out.println(app);ClassLoader ext app.getParent();System.out.println(ext);ClassLoader bootstrap ext.getParent();System.out.println(bootstrap);}结果 sun.misc.Launcher$AppClassLoader18b4aac2 sun.misc.Launcher$ExtClassLoader6d03e736 null程序中的默认类加载器为 AppClassLoader 。一般情况下Java 应用中的类都是由 AppClassLoader 加载器加载。其通过 ClassLoader.getSystemClassLoader() 方法获取。 Java 代码中不能直接获取引导类加载器实例。所以示例中 bootstrap 为 null 获取加载器加载的路径 // 获取 Bootstrap 加载器的加载路径URL[] urls Launcher.getBootstrapClassPath().getURLs();for(URL url : urls){System.out.println(url.getFile());}System.out.println();// 获取扩展类加载器加载的的路径String dirs System.getProperty(java.ext.dirs);System.out.println(dirs); 结果 /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/resources.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/rt.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/sunrsasign.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/jsse.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/jce.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/charsets.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/lib/jfr.jar /C:/Program%20Files/Java/jdk1.8.0_181/jre/classesC:\Program Files\Java\jdk1.8.0_181\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\extBootstrap 加载器的加载路径下的 jar 包文件包含的类由 Bootstrap 加载器加载两个 ext 目录下的 jar 包下的类由 ExtClassLoader 加载器加强我们的应用程序classpath 属性下的类由 AppClassLoader 加载。 不同类对应的加载器 ClassLoader classLoader String.class.getClassLoader();System.out.println(classLoader);ClassLoader classLoader1 ExecutorTest.class.getClassLoader();System.out.println(classLoader1);结果 null sun.misc.Launcher$AppClassLoader18b4aac2说明 String 类是由引导类加载器加载其引导类加载器无法在代码中获取所以为 null 。ExecutorTest 是我们的示例对象其由 AppClassLoader 加载器加载。当然我们在 ext 目录下找到的 jar 包中的类由 ExtClassLoader 加载器加载。 自定义加载器 一般的 Java 程序中使用引导类加载器、扩展类加载器、系统类加载器相互作用即可。几乎不需要自定义类的加载器我们可以在某些情况下进行自定义加载器。 修改类的加载方式还比如我们对编译的源码进行了加密在类加载时需要解密等 自定义加载器的方式 继承 ClassLoader 重写 findClass(String name) 方法按照 URLClassLoader.FactoryURLClassLoader 继承 URLClassLoader 的方式继承 URLClassLoader 来实现即可。 URLClassLoader 可以加载 jar 包下的类 package com.yyoo.jvm;import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;Getter Setter AllArgsConstructor public class MyClassLoader extends ClassLoader{/*** 当前加载器的 class 文件根路径*/private String classRootPath;Overrideprotected Class? findClass(String name) throws ClassNotFoundException {// 使用 io 流读取.class 字节码文件然后使用父类的 defineClass 方法返回为 Class 类try (InputStream in new FileInputStream(getClassRootPath()\\name.replaceAll(.,\\).class)){byte[] b new byte[1024];int len in.read(b);return defineClass(name,b,0,len);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}throw new ClassNotFoundException();}} name 参数使用class的全类名即可。注我们示例使用了 lombok 插件。 获取类的加载器的方式 // 获取当前类的ClassLoader Object o new Object(); System.out.println(o.getClass().getClassLoader());// 获取当前线程上下文的ClassLoder System.out.println(Thread.currentThread().getContextClassLoader());// 获取当前系统的 ClassLoder System.out.println(ClassLoader.getSystemClassLoader());双亲委派机制 类的加载过程 类的加载器收到类的加载请求时它不会立马去加载而且把加载请求委托给父类加载器去执行。如果父类加载器还有父类加载器则会进一步委托给父类加载器加载直到最顶层的类加载器。如果父类加载器可以完成类的加载则由父类加载器加载该类如果父类加载器无法加载子加载器才会尝试自己加载 以上整个过程称为双亲委派机制。 示例1 public static void main(String[] args) throws ClassNotFoundException {String classRootPath D:\\work\\code\\mytest\\peixun\\target\\classes;// 同一个 ClassLoader 实例加载同一个 Class 得到的是同一个 Class 对象ClassLoader my new MyClassLoader(classRootPath);Class a my.loadClass(com.yyoo.jvm.MyEmp);Class b my.loadClass(com.yyoo.jvm.MyEmp);System.out.println(a b);// true// 同一个 ClassLoader 的不同实例加载同一个 Class 文件得到的也是同一个 Class 对象ClassLoader my1 new MyClassLoader(classRootPath);Class c my1.loadClass(com.yyoo.jvm.MyEmp);System.out.println(a c);// true// 不同的 ClassLoader 加载同一个 Class 文件得到的也是同一个 Class 对象ClassLoader app ClassLoader.getSystemClassLoader();Class d app.loadClass(com.yyoo.jvm.MyEmp);System.out.println(a d);// trueSystem.out.println(a.getClassLoader());// 系统类加载器System.out.println(d.getClassLoader());// 系统类加载器}注MyClassLoader 即为我们上面自定义的 ClassLoader。 根据双亲委派机制来解释该现象我们自定义加载器的 classRootPath 其实就是我们应用的 classPath而 classPath 下的类是由系统类加载器加载的而且其加载的始终是 classPath 下的类而我们的 ClassRootPath 下的类永远不会加载除非我们自定义加载的类和系统类加载器加载的类全类名有不同的地方 或者 classPath 下没有该类。 示例2 示例1的前提是MyEmp 的 .class 文件存在于我们应用的 classPath 路径下示例 2 我们将 classPath 路径下的 .class 文件删除并按包路径创建文件夹在 D 盘根路径下Java 的几大类加载器加载的路径和目录之外再次执行 String classRootPath D:; // 同一个 ClassLoader 实例加载同一个 Class 得到的是同一个 Class 对象 ClassLoader my new MyClassLoader(classRootPath); Class a my.loadClass(com.yyoo.jvm.MyEmp); Class b my.loadClass(com.yyoo.jvm.MyEmp);System.out.println(a b);// 同一个 ClassLoader 的不同实例加载同一个 Class 文件得到的不是同一个 Class 对象 ClassLoader my1 new MyClassLoader(classRootPath); Class c my1.loadClass(com.yyoo.jvm.MyEmp); System.out.println(a c);System.out.println(a.getClassLoader()); System.out.println(c.getClassLoader());结果 true false com.yyoo.jvm.MyClassLoader3f99bd52 com.yyoo.jvm.MyClassLoader3a71f4dd可以看到在 系统类加载器、扩展类加载器、启动类加载器加载的路径之外的 .class 文件会使用我们自定义的加载器加载且不同的 MyClassLoader 实例加载的 Class 对象不是同一个。 双亲委派机制的好处 避免类的重复加载保护程序安全防止核心 API Java 核心类被随意篡改 Java 的 SPI 机制 SPIservice provider interface是 jdk 内置的一种服务提供发现机制。可以用来启用框架扩展和替换组件主要是被框架的开发人员使用比如java.sql.Driver接口,常用的关系型数据有 Mysql、Oracle、SQLServer、DB2 等这些不同类型的数据库使用的驱动程序各不相同那 JDK 不可能把所有厂商的驱动都实现只能制定一个标准接口其他不同厂商可以针对同一接口做出不同的实现各个数据库厂商根据标准来实现自己的驱动这就是SPI机制。 通俗点来说SPI 就是某个应用程序只提供接口规则具体的实现需要调用方通常该接口会有多个实现否则也就用不着 SPI 了在使用时自行实现其实现方式遵循 Java 的 SPI 机制。 比如我们要提供一个文件上传的接口其实现有如下几种方式服务器本地存储、上传到 ftp 服务器、上传到 minio、上传到云服务等等 1. 接口定义 public interface FileUpload {/*** 上传文件*/void upload();}2. 具体实现 public class LocalFileUpload implements FileUpload{Overridepublic void upload() {System.out.println(将文件存储到服务器本地路径下);} } public class MinIOFileUpload implements FileUpload{Overridepublic void upload() {System.out.println(将文件上传到 MinIOn 服务器);} }3. 配置 META-INF/services 文件 在应用的 META-INF/services/ 目录下目录不存在自行创建即可创建文件名称为 com.yyoo.spi.FileUpload 的文本文件 文件内容为 com.yyoo.spi.LocalFileUpload com.yyoo.spi.MinIOFileUpload4. 接口的使用 // load 方法如果不传 ClassLoader 则默认使用当前线程上下文的 Thread.currentThread().getContextClassLoader() // 这里即是系统类加载器我们也可以使用重载方法 load(ClassS service,ClassLoader loader) 来指定加载器 ServiceLoaderFileUpload serviceLoader ServiceLoader.load(FileUpload.class);// 获取迭代器或者直接使用 foreach 语句即可获取 META-INF/services/com.yyoo.spi.FileUpload 文件中配置的所有实现 for (FileUpload fileUpload : serviceLoader){System.out.println(fileUpload.getClass());System.out.println(fileUpload.getClass().getClassLoader());// 使用系统类加载器加载fileUpload.upload(); }执行结果 class com.yyoo.spi.LocalFileUpload sun.misc.Launcher$AppClassLoader18b4aac2 将文件存储到服务器本地路径下 class com.yyoo.spi.MinIOFileUpload sun.misc.Launcher$AppClassLoader18b4aac2 将文件上传到 MinIOn 服务器ServiceLoader 是 java.util 包提供的工具类其主要作用就是通过读取 META-INF/services 下的配置然后根据配置通过系统类加载器加载对应配置的实现类。 SPI 允许应用程序外部提供内部接口的实现从而改变了内部接口的行为在某种程度上规避了双亲委派机制思想核心 API 实现被改变。
http://www.hkea.cn/news/14395874/

相关文章:

  • 上海城建设计院网站wordpress判断使用不同模板
  • 三网合一的网站怎么做20个优秀的响应式设计html5网站模板
  • 天津公司网站制作wordpress本站主题
  • cms网站群在线查企业信息查询平台
  • 提供微信网站建设静态网站开发技术
  • 旅游网站建设的好处网站引流怎么做的
  • 清溪镇网站建设公司网站文档怎么加图片不显示不出来
  • 高端网站建设谷美开发游戏的职业叫什么
  • 北京的网站建设收费标准自己创建app
  • 系统之家win7纯净版广州seo网络优化公司
  • 厦门网站建设工作室网监大队让网站备案
  • 做地图特效的网站成都注册公司多少钱
  • 做效果图网站有哪些装饰公司简介内容
  • 无为县住房建设局网站首页logo免费一键生成
  • 房地产做网站公司文化建设
  • 网站建设产品经理职责四川建筑人员证书查询官网
  • 集团公司网站 案例学it需要什么学历
  • 网站怎么做qq微信登陆界面郴州网站设计公司
  • 一个模拟做实验的网站西安优化网站
  • 做网站知道访客ip做搜狗手机网站快速
  • 会计培训网站医疗机构网站
  • 网站建设卖点什么是软件定制开发
  • 企业网站标签页是什么网页编辑布局在线
  • 网站建设合同用贴印花税吗南宁企业门户网站建设价格
  • 网站 工信部备案 收回别人抄袭网站设计怎么办
  • 织梦做仿站时 为何会发生本地地址跳转网站地址大连网站制作机构
  • 企业做网站哪家公司好跨境电商知名网站建设
  • 兰州企业建设网站软文的概念
  • 可视化响应式网站建设物流网站大全
  • 成立公司有什么好处和坏处seo狂人