openfire源码解读一 项目启动

一:org.jivesoftware.openfire.starter.ServerStarter中的main启动

二:首先获得ClassLoader(类加载器)

ClassLoader的知识。

  • 首先ClassLoader作用是加载Class文件到jvm中,供程序使用,java程序可以动态加载类定义,这个动态加载的机制就是通过ClassLoader来实现的。

  • ClassLoader 是加载Class文件的(ExtClassLoader和AppClassLoader也在此时被加载),那么ClassLoader又被谁加载呢?是一 个被不是java语言所编写的ClassLoader来加载的,这个ClassLoader就是bootstrapClassLoader(启动类加载 器)。这个加载器在jvm运行的时候加载java核心的api以满足java程序最基本的需求。其中包括用户定义的ClassLoader,用户定义的 ClassLoader就是通过程序创建的ClassLoader,那么也有非程序员创建的ClassLoader,就是jvm自己提供的吧(这句是自己 理解的)。用户自定义的ClassLoader有ExtClassLoader,ExtClassLoader加载java的扩展的api,也就是 /lib/ext中的类。用户自定义的ClassLoader还有AppClassLoader,AppClassLoader用户机器上的 CLASSPATH设置目录中的Class的,通常在没有指定ClassLoader的情况下,程序自定义的类由AppClassLoader加载

  • ClassLoader 的加载模式:双亲委托模式进行加载。该模式的原理是:某个自定义的ClassLoader加载Class的时候都会先委托他的parnet ClassLoader加载该Class,当parent ClassLoader加载失败,再由当前的ClassLoader加载该Class,但是如果该ClassLoader的parent ClassLoader为null那么该ClassLoader的parent就是bootstrapClassLoader。

  • 使用双亲委托模式的优点是:

    第一:避免重复加载,当父亲已经加载了该类,那么子ClassLoader就没有必要加载该class了。

    第二:安全因素。

三:获取当前类的类加载器的方法

private ClassLoader findParentClassLoader() {
    ClassLoader parent = Thread.currentThread().getContextClassLoader();
    if (parent == null) {
        parent = this.getClass().getClassLoader();
        if (parent == null) {
            parent = ClassLoader.getSystemClassLoader();
        }
    }
    return parent;
}

 类加载器的种类:

扫描二维码关注公众号,回复: 3871820 查看本文章
  •  bootstrap class Loader(引导类加载器) 用来加载java的核心类库

  •  extensions class loader(扩展类加载器) 用来加载java的扩展库Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类[ExtClassLoader]

  • 系统类加载器(system class loader)Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取它[AppClassLoader]

四:获取openfire的lib路径 

String libDirString = System.getProperty("openfire.lib.dir");

private static final String DEFAULT_LIB_DIR = "../lib";

File libDir;
if(libDirString != null) {
    //如果已指定了LIB目录属性,并且实际存在,否则使用默认目录。
    libDir = new File(libDirString);
    if (!libDir.exists()) {
        Log.warn("Lib directory " + libDirString + " does not exist. Using default " + DEFAULT_LIB_DIR);
        libDir = new File(DEFAULT_LIB_DIR);
    }
}else {
    libDir = new File(DEFAULT_LIB_DIR);
}

 五:获取项目路径

private static final String DEFAULT_ADMIN_LIB_DIR = "../plugins/admin/webapp/WEB-INF/lib";

String adminLibDirString = System.getProperty("openfireHome");
if (adminLibDirString == null) {
    adminLibDirString = DEFAULT_ADMIN_LIB_DIR;
}else {
    adminLibDirString = adminLibDirString+"/plugins/admin/webapp/WEB-INF/lib";
}
File adminLibDir = new File(adminLibDirString);
if (!adminLibDir.exists()) {
    Log.warn("Admin Lib Directory " + adminLibDirString + " does not exist. Web admin console may not work.");
}

六:创建了一个自定义的类加载器,该类加载器同时加载了所需要的jar包

ClassLoader loader = new JiveClassLoader(parent, libDir);
class JiveClassLoader extends URLClassLoader {

    JiveClassLoader(ClassLoader parent, File libDir) throws MalformedURLException {
        super(new URL[] { libDir.toURI().toURL() }, parent);

        File[] jars = libDir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                boolean accept = false;
                String smallName = name.toLowerCase();
                if (smallName.endsWith(".jar")) {
                    accept = true;
                }
                else if (smallName.endsWith(".zip")) {
                    accept = true;
                }
                return accept;
            }
        });

        // 如果找不到jar或zip文件,什么也不做。
        if (jars == null) {
            return;
        }

        // 排序 jars 否则不会按顺序加载 (e.g. it's not alphabetical)
        // 如果将补丁jar添加到LIB文件夹,用来修复或者安装,那顺序很重要
        Arrays.sort(jars);
        // 调用父类URLClassLoader的addURL方法加载文件到classpath中
        for (int i = 0; i < jars.length; i++) {
            if (jars[i].isFile()) {
                addURL(jars[i].toURI().toURL());
            }
        }
    }
}

七、设置自定义的类加载器为当前线程的类加载器

Thread.currentThread().setContextClassLoader(loader);

八、利用当前线程的类加载器加载类文件

Class containerClass = loader.loadClass("org.jivesoftware.openfire.XMPPServer");

猜你喜欢

转载自blog.csdn.net/u014094343/article/details/83589645