首页新闻找找看学习计划

tomcat源码, 为何用反射实例化而不用new关键字?

0
悬赏园豆:100 [待解决问题]

我观察了tomact目录结构发现只有jar文件,没有我们一般编写javase那样的编译后的class文件。

 

为何tomcat里面有些类会用发射,有些类直接使用new关键字。

1.反射

 public void init() throws Exception {

        initClassLoaders();

        Thread.currentThread().setContextClassLoader(catalinaLoader);

        SecurityClassLoad.securityClassLoad(catalinaLoader);

        // Load our startup class and call its process() method
        if (log.isDebugEnabled())
            log.debug("Loading startup class");
        Class<?> startupClass =
            catalinaLoader.loadClass
            ("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.newInstance();
      //  Object startupInstance = new org.apache.catalina.startup.Catalina();
        // Set the shared extensions class loader
        if (log.isDebugEnabled())
            log.debug("Setting startup class properties");
        String methodName = "setParentClassLoader";
        Class<?> paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);

        catalinaDaemon = startupInstance;

    }

 

2.Catalina类:

  protected Digester createStartDigester() {
        long t1=System.currentTimeMillis();
        // Initialize the digester
        Digester digester = new Digester();
        digester.setValidating(false);
        digester.setRulesValidation(true);
        HashMap<Class<?>, List<String>> fakeAttributes = new HashMap<>();
        ArrayList<String> attrs = new ArrayList<>();
        attrs.add("className");
        fakeAttributes.put(Object.class, attrs);
        digester.setFakeAttributes(fakeAttributes);
        digester.setUseContextClassLoader(true);
        .............

 

 

如上图所示,在1图中可以直接使用  Object startupInstance = new Catalina();吗?

因为tomcat目录中没有Catalina这个类,但是有.jar文件中含有这个类,我们可以这样使用吗?

 

为何tomcat源码中 部分使用反射生成实例,而部分则使用new关键字呢?而且tomcat启动有一个函数的代码是把bin目录下的jar包全部加载 (没有加载全部的类) 又是为何呢?

進击の程序猿的主页 進击の程序猿 | 初学一级 | 园豆:102
提问于:2016-09-22 21:07
< >
分享
所有回答(5)
0

看心情与情况.自己写代码就知道了.到时候自然知道.

该用什么的时候用什么就行.别纠结.

吴瑞祥 | 园豆:28770 (高人七级) | 2016-09-22 22:58
0

new 都是可以new的,但是有时候不需要new自己的类,因为Java这个东西有个特性叫多态,意为多种状态,可以让一个对象存在各个类的各个状态中。所以没必要去管这些 该怎么用 就怎么用 Java不是很难

钓一条大鱼 | 园豆:164 (初学一级) | 2016-09-23 02:53

多态可不是多种状态。

支持(0) 反对(0) Daniel Cai | 园豆:10374 (专家六级) | 2016-09-27 16:31

@Daniel Cai: 

支持(0) 反对(0) 钓一条大鱼 | 园豆:164 (初学一级) | 2016-09-27 21:19

@钓一条大鱼: 人家也说了是字面意思。多种状态是指对象在不同时刻所持有的不同信息。

class User

{

 private int Status;

}

多态则是指从相同对象派生或实现的不同。

interface ISoundable

{

 void Play();

}

class Duck:ISoundable

{

 public void Play()

{

 Console.WriteLine("gaga");

}

class Cat...

}

支持(0) 反对(0) Daniel Cai | 园豆:10374 (专家六级) | 2016-09-28 09:38
1

用反射是运行时依赖,用new是编译时依赖.

 

小彬 | 园豆:947 (小虾三级) | 2016-09-23 09:18
0

主要在于

1 性能考虑

自行搜索

2 类加载器的考虑

假设A类中使用new 创建类C,那么C的类加载器是和 A一样的

假设A类中使用反射创建类C,那么C的类加载器是和 A可能是不一样的, C会使用当前的线程绑定类加载器

 

 

CanntBelieve | 园豆:55 (初学一级) | 2016-09-28 16:11
0

有几点考虑:

  1. Tomcat中有conf/server.xml和web.xml配置文件,允许用户自定义需要实例化的类,所以,必须使用反射机制进行动态实例化。
  2. 为了安全考虑,tomcat中载入器只允许载入特定目录下的servlet类,所以要实现自定义的类加载器。
  3. 为了实现tomcat运行过程中的重新部署,tomcat会有一个线程专门定时查询目录下的类是否改变,如果改变,则会动态重新加载
yxlaisj | 园豆:202 (菜鸟二级) | 2019-06-08 12:12
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册