ps做网站页面设置为多大,聊城网站建设信息,常德做网站的公司,网站建设维护是做什么的提示#xff1a;从JDK源码级别彻底剖析JVM类加载机制、双亲委派机制、全盘负责委托机制、打破双亲委派机制的程序、Tomcat打破双亲委派机制、tomcat自定义类加载器详解、tomcat的几个主要类加载器、手写tomcat类加载器 文章目录 前言一、loadClass的类加载大概有如下步骤二、j… 提示从JDK源码级别彻底剖析JVM类加载机制、双亲委派机制、全盘负责委托机制、打破双亲委派机制的程序、Tomcat打破双亲委派机制、tomcat自定义类加载器详解、tomcat的几个主要类加载器、手写tomcat类加载器 文章目录 前言一、loadClass的类加载大概有如下步骤二、java中类加载器的分类三、双亲委派机制3.1、为什么要设计双亲委派机制3.2、什么是全盘负责委托机制。3.3、打破双亲委派机制的程序: 4、Tomcat打破双亲委派机制4.1、tomcat解决什么问题4.2、tomcat如果使用双亲委派机制行不行4.3、tomcat自定义类加载器详解4.4、自定义类加载器示例4.5、tomcat的实现 总结 前言
例如随着人工智能的不断发展机器学习这门技术也越来越重要很多人都开启了学习机器学习本文就介绍了机器学习的基础内容。 一、loadClass的类加载大概有如下步骤
加载 -》验证 -》准备 -》解析 -》初始化 -》使用 -》卸载。
加载在硬盘中查找并通过io读入字节码文件。使用到类时才会加载。例如调用类的main方法new对象等在加载阶段会在内存中生成一个点这个类的java.lang.Class对象作为方法区这个类的各种数据的访问入口验证校验字节码文件的正确性。正确的字节码文件应该是以 cafe babe 开头的并且是0034 这样的不能说随便一个格式的字节码都能正确识别准备是会将变量先赋一个默认值如果是boolean就是false如果是integer就是0.比如你定义的 int a 10。那么准备这部就是int a0解析将符号引用转变为直接引用其实就是转换为内存地址。比如说public static void main(String [] args)。这些符号肯定要存到内存中的而且是存的内存地址。就是把这些符号转换为地址的过程这个步骤有个名词叫做静态链接。动态链接是指在程序运行期间完成的将符号引用替换为直接引用。(在加载的时候还不执行在运行的时候才执行的。)初始化对类的静态变量初始化为指定的值执行静态代码块。(一些静态代码块也是这个阶段去执行。可以参考一下类的加载顺序子类的静态代码块-》父类的静态代码块-》父类的构造方法-》子类的构造方法)
二、java中类加载器的分类
引导类加载器(根加载器BootStarpClassLoader)负责加载支撑JVM运行的位于JRE的lib目录下的核心类库比如rt.jar、charsets.jar等扩展类加载器(扩展类加载器ExtClassLoader)负责加载支撑JVM运行的位于JRE的lib目录下的ex扩展目录的jar包应用程度类加载器(系统类加载器AppClassLoader)负责加载ClassPath路径下的类包主要就是加载你自己写的那些类自定义类加载器(继承了java.lang.ClassLoader的类加载器)负责加载用户自定义路径下的类包(项目的classPath下找)
引导类加载器不用管是c语言实现的。c语言在实现引导类加载器的时候会通过一个Launcher类初始化这个Launcher类的时候把扩展类加载器、应用程序类加载器给构造出来并且把他俩的关系给搞出来。扩展类加载器是应用程序类加载器的父类。 通过Java命令执行代码的大体流程如下 类加载器的初始化过程 Launcher类是类加载的关键类。而extClassLoader、appClassLoader、的父类是ClassLoader.java类。
参见类运行加载全过程图可知其中会创建JVM启动器实例sun.misc.Launcher。
sun.misc.Launcher初始化使用了单例模式设计保证一个JVM虚拟机内只有一个
sun.misc.Launcher实例。
在Launcher构造方法内部其创建了两个类加载器分别是
sun.misc.Launcher.ExtClassLoader(扩展类加载器)和sun.misc.Launcher.AppClassLoader(应
用类加载器)。
JVM默认使用Launcher的getClassLoader()方法返回的类加载器AppClassLoader的实例加载我们
的应用程序。1 //Launcher的构造方法
2 public Launcher() {3 Launcher.ExtClassLoader var1;
4 try {
5 //构造扩展类加载器在构造的过程中将其父加载器设置为null
6 var1 Launcher.ExtClassLoader.getExtClassLoader();
7 } catch (IOException var10) {
8 throw new InternalError(Could not create extension class loader, var10);
9 }
10
11 try {
12 //构造应用类加载器在构造的过程中将其父加载器设置为ExtClassLoader
13 //Launcher的loader属性值是AppClassLoader我们一般都是用这个类加载器来加载我们自
己写的应用程序
14 this.loader Launcher.AppClassLoader.getAppClassLoader(var1);
15 } catch (IOException var9) {
16 throw new InternalError(Could not create application class loader, var9);
17 }
18
19 Thread.currentThread().setContextClassLoader(this.loader);
20 String var2 System.getProperty(java.security.manager);
21 。。。 。。。 //省略一些不需关注代码
22
23 }三、双亲委派机制 双亲委派机制双亲委派机制简单的说就是先由父类加载父类没有了再由儿子加载。举个例子比如你现在要加载Math这个类那么就会
由应用程序类加载器(AppClassLoader)去扫描应用程序类加载器已经加载的类如果扫描到了直接返回。(刚进来肯定是没有直接委派给上级)如果应用程序类加载器(AppClassLoader)没有扫描到他就会委托他的父加载器扩展类加载器(ExtClassLoader)去加载扩展加载器也是一样先扫描扩展加载器已经加载的类(jdk中的ex包下的类)如果扫描到了直接返回如果扩展类加载器(ExtClassLoader)没扫描到就委托扩展加载器的父加载器引导类加载器(BootStarpClassLoader)去加载。他也是一样先扫描自己已经加载的类如果扫描到了(扫描jdk中的lib包的类)直接返回如果没扫描到就会委托他的子加载器扩展类加载器去加载。如果扩展类加载器(ExtClassLoader)扫描到他已经加载的类扫描到了直接返回如果没扫描到就会给他的子加载器(应用程序类加载器)去扫描。应用程序类加载器去扫描它应该扫描的路径也就是项目的classPath下的包扫描到了直接返回。(没扫描到报classNotFind) 简单总结一下双亲委派机制就是说先由父类去加载父类加载不到再由子类去加载子类最后也加载不到就会提示 class not find
思考一下为啥会是双亲委派呢每次都要先依次到最顶层然后最顶层没有还有依次往下到最下层这样性能不是会变低吗。第一次加载的时候可能确实性能会低但是一旦加载完毕了就直接存在应用程序类加载器了(这个里面有一个list是存的已经加载好的类)直接从里面读就行不用在依次到最上层的引导类加载器去获取类对象了。
我们常说的应用程序类加载器的父加载器是扩展类加载器并不是说应用程序类加载器继承了扩展类加载器而是说应用程序类加载器的其中一个属性(父加载器)的值 是扩展类加载器。
3.1、为什么要设计双亲委派机制
沙箱安全机制防止核心API类库被随意篡改。比如你自己写了一个java.lang.String.class类不会被加载(因为是先父类加载加载到了直接返回)避免类的重复加载当父类已经加载了该类时就没有必要子类在加载一遍了保证了被加载类的唯一性。 比如你手写了一个String类包路径也叫做java.lang.String。那么一上来应用程序类(最下级)加载器肯定是没有然后他委托给扩展类加载器然后扩展类加载器委托给引导类加载器然后引导类加载器直接扫描到就直接返回了就不往下走了所以你自己手写的Stting类没起到作用直接用的还是java的String类。
3.2、什么是全盘负责委托机制。
全盘负责委托机制指当一个ClassLoader装载一个类时除非显示的使用另外一个classLoader否则该类所依赖及引用的类也由这个ClassLoader载入。(比如说是appClassLoader加载的UserA类然后UserA类中有一个静态属性是UserB类因为是静态的嘛A加载的时候B也得被加载。那么appClassLoader在创建userA对象的时候就直接把userA、userB同时创建了)
3.3、打破双亲委派机制的程序:
tomcat。假设我tomcat要同时部署2个war包一个是A、一个是B。其中A是依赖的spring4B是依赖是spring5。那么两个spring中肯定有很多包名是全限定路径都一样那肯定不能是双亲委派机制走第一个了第二个就不走了那肯定是不行的。所以tomcat一定是打破了双亲委派机制的。
4、Tomcat打破双亲委派机制
4.1、tomcat解决什么问题
以tomcat类加载为例我们思考一下tomcat作为一个web容器他要解决什么问题
一个web容器可能要部署多个不同的应用程序(服务)不同的应用程序可能会依赖同一个第三方类库的不同版本(比如A服务是依赖的spring3b服务是依赖的spring4)因此要保证每个服务的类库都是独立的保证相互隔离。部署在同一个web容器中相同的类库的相同版本可以共享。否则如果容器内有10个服务那么就要有10份相同的类库加载进虚拟机。(如果a、b、c等10个服务都依赖了spring2.3难道要把spring2.3内的类加载10遍吗)web容器也有自己依赖的类库不能与应用程序的类库混淆。基于安全考虑应该让容器中的类库和程序的类库隔离开来。web容器要支持jsp的修改我们知道jsp文件最终也是要编译成clas文件才能在虚拟机中运行但程序运行后修改jsp已经是司空见惯的事web容器需要支持jsp修改后不用重启。
4.2、tomcat如果使用双亲委派机制行不行
不行的为什么 5. 1.第一个问题如果使用默认的类加载机制那么是无法加载两个类库的不同版本的默认的双亲委派机制是不管你哪个版本只关心你的全限定路径一样不一样 6. 2.第二个问题默认的类加载器是能够实现的因为他的职责就是保证唯一性。 7. 3.和第一个问题一样
4.我们想一下要怎么实现tomcat的热加载。jsp其实也是class文件那么如果修改了但类名还一样类加载器会直接取方法区中已存在的修改后的jsp是不会被重新加载的。那么怎么办呢我们可以直接卸载掉这个jsp文件的类加载器所以呢就是给每个jsp文件对应一个唯一的类加载器当一个jsp文件修改了就直接卸载这个jsp类加载器。重新创建类加载器重写加载jsp文件。(搞个线程去监听这个jsp文件夹的变动有变动了就重新加载)
4.3、tomcat自定义类加载器详解 tomcat的几个主要类加载器
commonLoaderTomcat最基本的类加载器加载路径的class可以被tomcat容器本身及各个Webapp访问catalinaLoaderTomcat容器私有的类加载器加载路径中的class对于Webapp不可见sharedLoader各个Webapp共享的类加载器加载路径的class对于所有Webapp可见但是对于Tomcat容器不可见WebappClassLoader各个Webapp私有的类加载器加载路径中的class只对当前webapp可见比如加载war包里相关的类每个war包应用都有自己的WebappClassLoader实现相互隔离比如不同war包引入了不同的spring版本这样实现就能加载各自的spring版本。
大概是每个war包都加载自己war内的类然后tomcat有几个war包就有几个war的加载器(webAppClassLoader)。然后其他类还是会委托给对应的上级类加载器。
从图中的委派关系中可以看出
CommonClassLoader能加载的类都可以被CatalinaClassLoader和SharedClassLoader使用从而实现了公有类库的共用而CatalinaClassLoader和SharedClassLoader自己能加载的类则与对方相互隔离。WebAppClassLoader可以使用SharedClassLoader加载到的类但各个WebAppClassLoader实例之间相互隔离。JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件它出现的目的就是为了被丢弃当Web容器检测到JSP文件被修改时会替换掉目前的JasperLoader的实例并通过再建立一个新的Jsp类加载器来实现JSP文件的热加载功能
4.4、自定义类加载器示例
自定义类加载器只需要继承 java.lang.ClassLoader 类该类由俩个核心方法一个是loadClass(String,boolean)实现了双亲委派机制还有一个是findClass默认实现是空方法所以我们自定义类加载器主要是重写findClass方法。 大致步骤 1、继承 ClassLoader 类 2、重写 findClass 方法。 3、重写loadClass方法(想跨过双亲委派机制就重写不想跨过就不需要写) 全部代码如下 其中不重写 loadClass 方法的时候是实现自定义类加载器去加载类的方法 其中重写了 loadClass 方法的时候是实现了跨过双亲委派机制的去用自定义类加载器去加载的实现。
package com.zheng.config;import java.io.FileInputStream;
import java.lang.reflect.Method;/*** author: ztl* date: 2023/11/18 22:29* desc: 自己的自定义类加载器* 自定义类加载器只需要继承 java.lang.ClassLoader 类这个类由俩个核心方法* loadClass(String,boolean) 实现了双亲委派机制* findClass 实现了空方法(所以我们自定义类加载器主要是重写findClass方法)*/
public class MyClassLoaderTest {static public class MyClassLoader extends ClassLoader {private String classPath;public MyClassLoader(String classPath){this.classPath classPath;}/*** 这个是读取class包用的* param name* return* throws Exception*/private byte[] loadByte(String name) throws Exception {name name.replaceAll(\\., /);FileInputStream fis new FileInputStream(classPath / name .class);int len fis.available();byte[] data new byte[len];fis.read(data);fis.close();return data;}/**** param name* return 这个是自定义加载器要用的* date: 2023/11/19 17:38* content:* name就是类的全限定路径* defineClass 是ClassLoader中的方法*/protected Class? findClass(String name) throws ClassNotFoundException {try {byte[] data loadByte(name);//name 类名。 data 类的二进制数组文件return defineClass(name, data, 0, data.length);} catch (Exception e) {e.printStackTrace();throw new ClassNotFoundException();}}/*** 这个是打破双亲委派机制用的* 正常的loadClass是双亲委派式的读取class文件。* 但是你现在不是想打破双亲委派嘛那就重写java的双亲委派走自己的加载程序就可以打破了**/protected Class? loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass? c findLoadedClass(name);if (c null) {long t0 System.nanoTime();// 这几行是双亲委派的代码,注掉他直接让他 cnull走自己的findClass
// try {
// if (parent ! null) {
// c parent.loadClass(name, false);
// } else {
// c findBootstrapClassOrNull(name);
// }
// } catch (ClassNotFoundException e) {
// // ClassNotFoundException thrown if class not found
// // from the non-null parent class loader
// }// 但是由于User1继承了Object类所以初始化user的时候就会初始Object// 由于Object是由BooStrapClassLoader加载的你没法直接不走双亲委派所以呢加个判断// 如果是我们自己的类则走自己的类加载器去加载如果是Object之类的类就走原来的双亲委派机制if (!name.startsWith(com.zheng.po)){// 走jdk的双亲委派机制c this.getParent().loadClass(name);}else {// 走自己重写的findClass类c findClass(name);}if (c null) {// If still not found, then invoke findClass in order// to find the class.long t1 System.nanoTime();c findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}}/**** content 测试自定义类加载器* return* date: 2023/11/19 18:07*/public static void main(String args[]) throws Exception {//初始化自定义类加载器会先初始化父类ClassLoader其中会把自定义类加载器的父加载器设置为应用程序类加载器AppClassLoader// 自定义类加载器的加载路径。MyClassLoader classLoader new MyClassLoader(D:/test);//D盘创建 com/zheng/po 几级目录将User类的复制类User1.class丢入该目录// 1、这个 com/zheng/po 就是你user1的包路径 2、这个必须是.class文件不能是 .java文件Class clazz classLoader.loadClass(com.zheng.po.User1);Object obj clazz.newInstance();Method method clazz.getDeclaredMethod(sout, null);method.invoke(obj, null);// 父加载器有就用父加载器的然后直接返回父加载器没有就用子加载器的结果// 如果你的appClassLoader就有class1的话就会打印出来 sun.misc.Launcher$AppClassLoader// 如果你的AppClassLoader里面没有的话就会走自己的 MyClassLoader。com.zheng.config.MyClassLoaderTest$MyClassLoader// 因为你的项目内现在有一个 com.zheng.po.user1.class// 然后d盘下面还有一个 com.zheng.po.user1.class// 所以他们的类名一模一样找到一个就直接返回了。就跟你自己手写一个String类和java的String类一样用上级的类加载器的String类// 如果已经重写了 loadClass 那么就是打破双亲委派机制的 com.zheng.config.MyClassLoaderTest$MyClassLoaderSystem.out.println(clazz.getClassLoader().getClass().getName());}}
4.5、tomcat的实现
tomcat的实现(不同的war包中去加载不同的类。这个类的全限定路径一样名字一样的话。) // tomcat就是这么实现的用同一个类(MyClassLoader)的两个实现(classLoader1、classLoader2)去加载不同的类 (跟上面的一样就是main方法改了改。) 代码块1
public static void main(String args[]) throws Exception {//初始化自定义类加载器会先初始化父类ClassLoader其中会把自定义类加载器的父加载器设置为应用程序类加载器AppClassLoader// 自定义类加载器的加载路径。MyClassLoader classLoader new MyClassLoader(D:/test);//D盘创建 com/zheng/po 几级目录将User类的复制类User1.class丢入该目录// 1、这个 com/zheng/po 就是你user1的包路径 2、这个必须是.class文件不能是 .java文件Class clazz classLoader.loadClass(com.zheng.po.User1);Object obj clazz.newInstance();Method method clazz.getDeclaredMethod(sout, null);method.invoke(obj, null);// 父加载器有就用父加载器的然后直接返回父加载器没有就用子加载器的结果// 如果你的appClassLoader就有class1的话就会打印出来 sun.misc.Launcher$AppClassLoader// 如果你的AppClassLoader里面没有的话就会走自己的 MyClassLoader。com.zheng.config.MyClassLoaderTest$MyClassLoader// 因为你的项目内现在有一个 com.zheng.po.user1.class// 然后d盘下面还有一个 com.zheng.po.user1.class// 所以他们的类名一模一样找到一个就直接返回了。就跟你自己手写一个String类和java的String类一样用上级的类加载器的String类// 如果已经重写了 loadClass 那么就是打破双亲委派机制的 com.zheng.config.MyClassLoaderTest$MyClassLoaderSystem.out.println(clazz.getClassLoader().getClass().getName());System.out.println();// tomcat就是这么实现的用同一个类(MyClassLoader)的两个实现(classLoader1、classLoader2)去加载不同的类MyClassLoader classLoader1 new MyClassLoader(D:/test1);Class clazz1 classLoader1.loadClass(com.zheng.po.User2);Object obj1 clazz1.newInstance();Method method1 clazz1.getDeclaredMethod(sout, null);method1.invoke(obj1, null);System.out.println(clazz1.getClassLoader().getClass().getName());
}代码块2
package com.zheng.config;import java.io.FileInputStream;
import java.lang.reflect.Method;/*** author: ztl* date: 2023/11/18 22:29* desc: 自己的自定义类加载器* 自定义类加载器只需要继承 java.lang.ClassLoader 类这个类由俩个核心方法* loadClass(String,boolean) 实现了双亲委派机制* findClass 实现了空方法(所以我们自定义类加载器主要是重写findClass方法)*/
public class MyClassLoaderTest {static public class MyClassLoader extends ClassLoader {private String classPath;public MyClassLoader(String classPath){this.classPath classPath;}/*** 这个是读取class包用的* param name* return* throws Exception*/private byte[] loadByte(String name) throws Exception {name name.replaceAll(\\., /);FileInputStream fis new FileInputStream(classPath / name .class);int len fis.available();byte[] data new byte[len];fis.read(data);fis.close();return data;}/**** param name* return 这个是自定义加载器要用的* date: 2023/11/19 17:38* content:* name就是类的全限定路径* defineClass 是ClassLoader中的方法*/protected Class? findClass(String name) throws ClassNotFoundException {try {byte[] data loadByte(name);//name 类名。 data 类的二进制数组文件return defineClass(name, data, 0, data.length);} catch (Exception e) {e.printStackTrace();throw new ClassNotFoundException();}}/*** 这个是打破双亲委派机制用的* 正常的loadClass是双亲委派式的读取class文件。* 但是你现在不是想打破双亲委派嘛那就重写java的双亲委派走自己的加载程序就可以打破了**/protected Class? loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass? c findLoadedClass(name);if (c null) {long t0 System.nanoTime();// 这几行是双亲委派的代码,注掉他直接让他 cnull走自己的findClass
// try {
// if (parent ! null) {
// c parent.loadClass(name, false);
// } else {
// c findBootstrapClassOrNull(name);
// }
// } catch (ClassNotFoundException e) {
// // ClassNotFoundException thrown if class not found
// // from the non-null parent class loader
// }// 但是由于User1继承了Object类所以初始化user的时候就会初始Object// 由于Object是由BooStrapClassLoader加载的你没法直接不走双亲委派所以呢加个判断// 如果是我们自己的类则走自己的类加载器去加载如果是Object之类的类就走原来的双亲委派机制if (!name.startsWith(com.zheng.po)){// 走jdk的双亲委派机制c this.getParent().loadClass(name);}else {// 走自己重写的findClass类c findClass(name);}if (c null) {// If still not found, then invoke findClass in order// to find the class.long t1 System.nanoTime();c findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}}/**** content 测试自定义类加载器* return* date: 2023/11/19 18:07*/public static void main(String args[]) throws Exception {//初始化自定义类加载器会先初始化父类ClassLoader其中会把自定义类加载器的父加载器设置为应用程序类加载器AppClassLoader// 自定义类加载器的加载路径。MyClassLoader classLoader new MyClassLoader(D:/test);//D盘创建 com/zheng/po 几级目录将User类的复制类User1.class丢入该目录// 1、这个 com/zheng/po 就是你user1的包路径 2、这个必须是.class文件不能是 .java文件Class clazz classLoader.loadClass(com.zheng.po.User1);Object obj clazz.newInstance();Method method clazz.getDeclaredMethod(sout, null);method.invoke(obj, null);// 父加载器有就用父加载器的然后直接返回父加载器没有就用子加载器的结果// 如果你的appClassLoader就有class1的话就会打印出来 sun.misc.Launcher$AppClassLoader// 如果你的AppClassLoader里面没有的话就会走自己的 MyClassLoader。com.zheng.config.MyClassLoaderTest$MyClassLoader// 因为你的项目内现在有一个 com.zheng.po.user1.class// 然后d盘下面还有一个 com.zheng.po.user1.class// 所以他们的类名一模一样找到一个就直接返回了。就跟你自己手写一个String类和java的String类一样用上级的类加载器的String类// 如果已经重写了 loadClass 那么就是打破双亲委派机制的 com.zheng.config.MyClassLoaderTest$MyClassLoaderSystem.out.println(clazz.getClassLoader().getClass().getName());}} 总结
我们面试中常说的jvm调优tomcat调优都需要我们了解底层原理才能更好的去优化因此了解这些组件的底层原理还是挺有必要的。 文章转载自: http://www.morning.qclmz.cn.gov.cn.qclmz.cn http://www.morning.sqgqh.cn.gov.cn.sqgqh.cn http://www.morning.ghcfx.cn.gov.cn.ghcfx.cn http://www.morning.dsxgc.cn.gov.cn.dsxgc.cn http://www.morning.cljmx.cn.gov.cn.cljmx.cn http://www.morning.kmqms.cn.gov.cn.kmqms.cn http://www.morning.nbnq.cn.gov.cn.nbnq.cn http://www.morning.qmbpy.cn.gov.cn.qmbpy.cn http://www.morning.kgnrh.cn.gov.cn.kgnrh.cn http://www.morning.tfgkq.cn.gov.cn.tfgkq.cn http://www.morning.wfwqr.cn.gov.cn.wfwqr.cn http://www.morning.ffdyy.cn.gov.cn.ffdyy.cn http://www.morning.huxinzuche.cn.gov.cn.huxinzuche.cn http://www.morning.xsctd.cn.gov.cn.xsctd.cn http://www.morning.rrjzp.cn.gov.cn.rrjzp.cn http://www.morning.pcqxr.cn.gov.cn.pcqxr.cn http://www.morning.dbfj.cn.gov.cn.dbfj.cn http://www.morning.jqkjr.cn.gov.cn.jqkjr.cn http://www.morning.nypsz.cn.gov.cn.nypsz.cn http://www.morning.skrxp.cn.gov.cn.skrxp.cn http://www.morning.tsnwf.cn.gov.cn.tsnwf.cn http://www.morning.wxfjx.cn.gov.cn.wxfjx.cn http://www.morning.rbknf.cn.gov.cn.rbknf.cn http://www.morning.plxnn.cn.gov.cn.plxnn.cn http://www.morning.dxpzt.cn.gov.cn.dxpzt.cn http://www.morning.nbsbn.cn.gov.cn.nbsbn.cn http://www.morning.mhwtq.cn.gov.cn.mhwtq.cn http://www.morning.bhbxd.cn.gov.cn.bhbxd.cn http://www.morning.zylzk.cn.gov.cn.zylzk.cn http://www.morning.wblpn.cn.gov.cn.wblpn.cn http://www.morning.nkqrq.cn.gov.cn.nkqrq.cn http://www.morning.pqkrh.cn.gov.cn.pqkrh.cn http://www.morning.qqnjr.cn.gov.cn.qqnjr.cn http://www.morning.bksbx.cn.gov.cn.bksbx.cn http://www.morning.liyixun.com.gov.cn.liyixun.com http://www.morning.ynstj.cn.gov.cn.ynstj.cn http://www.morning.rrxnz.cn.gov.cn.rrxnz.cn http://www.morning.xlxmy.cn.gov.cn.xlxmy.cn http://www.morning.kwnbd.cn.gov.cn.kwnbd.cn http://www.morning.gqhgl.cn.gov.cn.gqhgl.cn http://www.morning.wpcfh.cn.gov.cn.wpcfh.cn http://www.morning.pqryw.cn.gov.cn.pqryw.cn http://www.morning.rdgb.cn.gov.cn.rdgb.cn http://www.morning.lkmks.cn.gov.cn.lkmks.cn http://www.morning.rqxch.cn.gov.cn.rqxch.cn http://www.morning.rblqk.cn.gov.cn.rblqk.cn http://www.morning.psdsk.cn.gov.cn.psdsk.cn http://www.morning.jyznn.cn.gov.cn.jyznn.cn http://www.morning.kxnjg.cn.gov.cn.kxnjg.cn http://www.morning.dwwbt.cn.gov.cn.dwwbt.cn http://www.morning.sqxr.cn.gov.cn.sqxr.cn http://www.morning.qytyt.cn.gov.cn.qytyt.cn http://www.morning.kltsn.cn.gov.cn.kltsn.cn http://www.morning.ydnxm.cn.gov.cn.ydnxm.cn http://www.morning.rsszk.cn.gov.cn.rsszk.cn http://www.morning.cmcjp.cn.gov.cn.cmcjp.cn http://www.morning.kndst.cn.gov.cn.kndst.cn http://www.morning.wmyqw.com.gov.cn.wmyqw.com http://www.morning.rxnxl.cn.gov.cn.rxnxl.cn http://www.morning.vaqmq.cn.gov.cn.vaqmq.cn http://www.morning.qtxwb.cn.gov.cn.qtxwb.cn http://www.morning.pbzgj.cn.gov.cn.pbzgj.cn http://www.morning.mqmxg.cn.gov.cn.mqmxg.cn http://www.morning.stprd.cn.gov.cn.stprd.cn http://www.morning.kqnwy.cn.gov.cn.kqnwy.cn http://www.morning.lbrwm.cn.gov.cn.lbrwm.cn http://www.morning.bncrx.cn.gov.cn.bncrx.cn http://www.morning.wqcz.cn.gov.cn.wqcz.cn http://www.morning.kclkb.cn.gov.cn.kclkb.cn http://www.morning.lkbdy.cn.gov.cn.lkbdy.cn http://www.morning.ryspp.cn.gov.cn.ryspp.cn http://www.morning.lywcd.cn.gov.cn.lywcd.cn http://www.morning.lzbut.cn.gov.cn.lzbut.cn http://www.morning.ftync.cn.gov.cn.ftync.cn http://www.morning.xhddb.cn.gov.cn.xhddb.cn http://www.morning.tsxg.cn.gov.cn.tsxg.cn http://www.morning.rhjhy.cn.gov.cn.rhjhy.cn http://www.morning.ryjl.cn.gov.cn.ryjl.cn http://www.morning.rntby.cn.gov.cn.rntby.cn http://www.morning.krtky.cn.gov.cn.krtky.cn