[tomcat7源码学习]初始化之ClassLoader

本文详细阐述了Tomcat初始化ClassLoader的过程,包括从配置文件获取加载器、解析路径类型、创建ClassLoader并注册到MBeanServer等关键步骤。重点介绍了如何在开发过程中动态加载jar文件,以及ClassLoader的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初始化之ClassLoader

初始化第2步就是ClassLoader,调用的initClassLoaders()

private void initClassLoaders() {
    try {
        commonLoader = createClassLoader("common", null);
        if( commonLoader == null ) {
            // no config file, default to this loader - we might be in a 'single' env.
            commonLoader=this.getClass().getClassLoader();
        }
        catalinaLoader = createClassLoader("server", commonLoader);
        sharedLoader = createClassLoader("shared", commonLoader);
    } catch (Throwable t) {
        handleThrowable(t);
        log.error("Class loader creation threw exception", t);
        System.exit(1);
    }
}

一共有3个ClassLoader,分别为commonLoader,catalinaLoader,sharedLoader,都是通过调用createClassLoader 来获取。

private ClassLoader createClassLoader(String name, ClassLoader parent)
        throws Exception {

    String value = CatalinaProperties.getProperty(name + ".loader");
    if ((value == null) || (value.equals("")))
        return parent;

    value = replace(value);

    List<Repository> repositories = new ArrayList<Repository>();

    StringTokenizer tokenizer = new StringTokenizer(value, ",");
    while (tokenizer.hasMoreElements()) {
        String repository = tokenizer.nextToken().trim();
        if (repository.length() == 0) {
            continue;
        }

        // Check for a JAR URL repository
        try {
            @SuppressWarnings("unused")
            URL url = new URL(repository);
            repositories.add(
                    new Repository(repository, RepositoryType.URL));
            continue;
        } catch (MalformedURLException e) {
            // Ignore
        }

        // Local repository
        if (repository.endsWith("*.jar")) {
            repository = repository.substring
                (0, repository.length() - "*.jar".length());
            repositories.add(
                    new Repository(repository, RepositoryType.GLOB));
        } else if (repository.endsWith(".jar")) {
            repositories.add(
                    new Repository(repository, RepositoryType.JAR));
        } else {
            repositories.add(
                    new Repository(repository, RepositoryType.DIR));
        }
    }

    ClassLoader classLoader = ClassLoaderFactory.createClassLoader
        (repositories, parent);

    // Retrieving MBean server
    MBeanServer mBeanServer = null;
    if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
        mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
    } else {
        mBeanServer = ManagementFactory.getPlatformMBeanServer();
    }

    // Register the server classloader
    ObjectName objectName =
        new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
    mBeanServer.registerMBean(classLoader, objectName);

    return classLoader;

}

###createClassLoader###

1.首先从配置文件中取出相应的loader,如果没有就返回父Loader,取配置文件的优先级为(参考类CatalinaProperties):

1.从System中获取catalina.config

2.从catalina.base下面的conf文件夹里面获取catalina.properties文件(一般情况下默认的就为这个)

3.包路径/org/apache/catalina/startup/catalina.properties

2.一般情况下在我们的${catalina.base}/conf/catalina.properties中默认都有配置

common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar

server.loadershared.loader都为空,所以默认情况下这两个loader都为common.loader

3.把从配置中取出的路径全部加到一个List<Repository>,每一个Repository都包含一个路径,并且会指明其类型,类型包括有:

public static enum RepositoryType {
    DIR,
    GLOB,
    JAR,
    URL
}

4.在取出所有路径后,通过ClassLoaderFactory.createClassLoader来获取classLoader,在ClassLoaderFactory.createClassLoader中解析完所有路径后,通过

return AccessController.doPrivileged(
    new PrivilegedAction<StandardClassLoader>() {
        @Override
        public StandardClassLoader run() {
            if (parent == null)
                return new StandardClassLoader(array);
            else
                return new StandardClassLoader(array, parent);
        }
    });

返回ClassLoader,所以tomcat里面的ClassLoader就为StandardClassLoader,这个又继承的URLClassLoader

5.把ClassLoader注册到MBeanServer

###总结###

1.tomcat中默认加载jar的顺序为${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar,并且里面用的LinkedHashSet来保存的这些路径,所以当我们有多个instance的时候,${catalina.base}应该会覆盖${catalina.home}里面同样的,以及如果有些公共的jar,需要提前加载的也应该可以配置到这里

2.看了StandardClassLoader,在开发过程中我们应该也可以动态加载jar。直接使用URLClassLoader加载

转载于:https://my.oschina.net/remind2010/blog/180078

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值