4
头图

Interviewer : you like to talk about the parent delegation mechanism in detail today?

candidate : Well, good.

candidate : mentioned last time: the class file is loaded into the JVM through the "class loader"

candidate : In order to prevent multiple copies of the same bytecode in memory, the parent delegation mechanism is used (it does not try to load the class by itself, but delegates the request to the parent loader to complete, and then upwards)

candidate : The native method classes in the JDK are generally loaded by the root loader (Bootstrp loader), the extension classes implemented in the JDK are generally loaded by the extension loader (ExtClassLoader), and the class files in the program are loaded by the system The device (AppClassLoader) implements loading.

candidate : This should be easy to understand, right?

Interviewer : Bird food (really)!

Interviewer : the topic, I would like to ask, what does it mean to break the parental delegation mechanism?

Candidate : It’s easy to understand, it means: as long as I load a class, I don’t look for it in the order of APPClassLoader->Ext ClassLoader->BootStrap ClassLoader, it’s broken.

candidate : Because the method of loading the core of the class is on the loadClass method of the LoaderClass class (the core implementation of the parent delegation mechanism)

candidate : So as long as I customize a ClassLoader and rewrite the loadClass method (do not start looking for the class loader according to the above), it will be regarded as breaking the parent delegation mechanism.

Interviewer : So simple?

candidate : Well, it's that simple

Interviewer : Do you know any scenario that undermines the parent delegation mechanism?

candidate : Tomcat is the most obvious

Interviewer : Tell me in detail?

candidate : In the beginning of the deployment project, we put the war package under the tomcat webapp, which means that a tomcat can run multiple web applications (:

candidate : right?

Interviewer : Well...

candidate : Suppose I now have two web applications, they both have a class called User, and their class fully qualified names are the same, for example, both are com.yyy.User. But their specific implementation is different

candidate : So how does Tomcat ensure that they will not conflict?

candidate : The answer is that Tomcat creates a class loader instance (WebAppClassLoader) for each Web application. The loader overrides the loadClass method and loads the classes in the current application directory first. Look up layer by layer (:

candidate : This will achieve the isolation of the Web application level

Interviewer : Well, do you know that Tomcat has other class loaders?

candidate : Well, I know

candidate : Not all dependencies under a web application need to be isolated. For example, Redis can be shared between web applications (if necessary), because if the version is the same, it is not necessary for each web application to be independent Load a copy.

candidate : The approach is also very simple, Tomcat adds a parent class loader (SharedClassLoader) to WebAppClassLoader, if WebAppClassLoader itself is not loaded into a certain class, then entrust SharedClassLoader to load.

candidate : (It's nothing more than putting the classes that need to be shared between applications in a shared directory)

Interviewer : Well...

candidate : In order to isolate the Web application from Tomcat's own classes, there is a class loader (CatalinaClassLoader) to load Tomcat's own dependencies

candidate : If Tomcat's own dependencies and Web applications need to be shared, then there is also a class loader (CommonClassLoader) to load to achieve sharing

candidate : The loading directory of each class loader can be viewed in the catalina.properties configuration file of tomcat

candidate : Let me draw a little bit of Tomcat’s class loading structure, otherwise it’s a bit abstract

Interviewer : Well, it’s okay, I understand, it’s interesting.

Interviewer : By the way, I would like to ask, don't you know about JDBC? I heard that it also destroys the parental delegation model. How do you understand it?

candidate : Eumm, whether this is broken, different people have different opinions.

candidate : JDBC defines the interface, the specific implementation class is implemented by various vendors (such as MySQL)

candidate : There is a rule for class loading: if a class is loaded by class loader A, then the dependent classes of this class are also loaded by "same class loader".

candidate : When we use JDBC, we use DriverManager to get Connection. DriverManager is in the java.sql package and is obviously loaded by the BootStrap class loader

candidate : When we use DriverManager.getConnection(), we must get the class implemented by the manufacturer.

candidate : But will BootStrap ClassLoader be able to load classes implemented by various vendors?

candidate : Obviously no, these implementation classes are not in the java package, how can they be loaded?

Interviewer : Well...

candidate : DriverManager's solution is to get the "thread context loader" when DriverManager is initialized

candidate : When getting Connection, it uses the "thread context loader" to load the Connection, and the thread context loader here is actually the App ClassLoader

candidate : So when getting Connection, first look for Ext ClassLoader and BootStrap ClassLoader, but these two loaders are definitely not loaded, and will eventually be loaded by App ClassLoader

Interviewer : Well...

candidate : In this case, some people think that the parent delegation mechanism is broken, because it should have been loaded by the BootStrap ClassLoader. As a result, you have a "thread context loader" and changed the "class loading" Device

Candidate : Some people think that the parent delegation mechanism has not been broken, and they just changed the class loading by the "thread context loader", but still obeyed: "Look up for the parent class loader to load in turn, but they can't find it. It is loaded by itself only when it is time." It is believed that the "principle" has not changed.

interviewer : Then I understand

This article summarizes :

  • pre-knowledge: JDK has three default class loaders: AppClassLoader, Ext ClassLoader, BootStrap ClassLoader. The parent loader of AppClassLoader is Ext ClassLoader, and the parent loader of Ext ClassLoader is BootStrap ClassLoader. The parent-child relationship here is not realized by inheritance, but by combination.
  • What is the parent delegation mechanism: loader first hands the class to the parent class loader to load, and the parent class loader does not find it before loading by itself.
  • Delegation Mechanism Purpose: to prevent multiple copies of the same bytecode in memory (safe)
  • class loading rules: If a class is loaded by the class loader A, then the dependent classes of this class are also loaded by the "same class loader".
  • breaks the parental delegation mechanism: customizes the ClassLoader and rewrites the loadClass method (as long as it is not uploaded to the parent loader for loading, even if it breaks the parental delegation mechanism)
  • Breaking the Parental Delegation Mechanism Case: Tomcat

    • In order to isolate between Web application classes, create a WebAppClassLoader class loader for each application
    • In order to share between Web application classes, use ShareClassLoader as the parent class loader of WebAppClassLoader. If the WebAppClassLoader loader cannot be found, try to load it with ShareClassLoader
    • In order to isolate Tomcat itself from the Web application class, use the CatalinaClassLoader class loader for isolation, and CatalinaClassLoader loads the classes of Tomcat itself
    • In order to share Tomcat and Web application classes, use CommonClassLoader as the parent class loader of CatalinaClassLoader and ShareClassLoader
    • The directories of ShareClassLoader, CatalinaClassLoader, and CommonClassLoader can be configured in Tomcat's catalina.properties
  • thread context loader: due to the rules of class loading, it is very likely that the parent loader depends on the class of the child loader when loading, resulting in failure to load successfully (BootStrap ClassLoader cannot load the classes of third-party libraries), so there is a "thread context loading Finder" to load.

Welcome to follow my WeChat public [16175fa950d95f Java3y ] to talk about Java interviews. The online interviewer series is being updated continuously!

[Online Interviewer-Mobile] The series updated twice a week!

[Online Interviewer-Computer] The series updated twice a week!

Original is not easy! ! Seek three links! !


Java3y
12.9k 声望9.2k 粉丝