.
/**
*
* null
* |
* |_ BoostrapClassLoader
* | |
* | |_ ExtClassLoader
* | |
* | |_ SystemClassLoader
* | |
* | |_ JDKDelegateClassLoader
* |
* |_ AgentClassLoader
* |
* |_ ContainerClassLoader
* |
* |_ BizClassLoader
* |
* |_ PluginClassLoader
*
*/
.
/**
*
* 类加载器的使用优先级(由高到底)
* 0、JDKDelegateClassLoader
* 1、ContainerClassLoader
* 2、hook级别类{前置}加载器
* 3、PluginClassLoader
* 4、BizClassLoader(当前类加载器)
* 5、AgentClassLoader、systemClassLoader
* 6、hook级别的{后置}类加载器
*
*
*
* systemClassLoader
* 继承:父类加载器是extClassLoader
* 初始化在:{@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#init()}
* 用途:1、加载systemClassLoader领域的类;2、加载extClassLoader领域的类
* 设置点:无
*
* JDKDelegateClassLoader
* 继承:父类加载器是extClassLoader
* 实例化在:{@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#init()}
* 用途:1、加载"java.home"路径下的jar包的类;2、加载extClassLoader领域的类
* 设置点:无
*
* AgentClassLoader
* 继承:没有父类加载器
* 实例化在:{@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#createAgentClassLoader()}
* 用途:用于加载{agent}领域的类
* 设置点:无
*
* ContainerClassLoader【ArkClassLoader】
* 继承:没有父类加载器
* 实例化在:{@link com.alipay.sofa.ark.bootstrap.AbstractLauncher#createContainerClassLoader(com.alipay.sofa.ark.spi.archive.ContainerArchive)}
* 用途:用于加载{ark-container}领域的类
* 设置点:{@link com.alipay.sofa.ark.bootstrap.AbstractLauncher#launch(java.lang.String[], java.lang.String, java.lang.ClassLoader)}
*
* BizClassLoader
* 继承:没有父类加载器
* 实例化在:{@link com.alipay.sofa.ark.container.service.biz.BizFactoryServiceImpl#createBiz(com.alipay.sofa.ark.spi.archive.BizArchive)}
* 用途:用于加载{业务}领域的类
* 设置点:{@link com.alipay.sofa.ark.container.model.BizModel#start(java.lang.String[])}
*
* PluginClassLoader
* 继承:没有父类加载器
* 实例化在:{@link com.alipay.sofa.ark.container.service.plugin.PluginFactoryServiceImpl#createPlugin(com.alipay.sofa.ark.spi.archive.PluginArchive)}
* 用途:用于加载{插件}领域的类
* 设置点:{@link com.alipay.sofa.ark.container.model.PluginModel#start()}
*
*/
.
/**
*
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#loadClass(java.lang.String name, boolean)
* {
* @see com.alipay.sofa.ark.container.service.classloader.BizClassLoader#loadClassInternal(java.lang.String name, boolean)
* {
* Class clazz = null;
*
* // 0. sun reflect related class throw exception directly【即:检查是否是{sun类}】
* if (classloaderService.isSunReflectClass(name)) {
* throw new ArkLoaderException(String.format("[ArkBiz Loader] %s : can not load class: %s, this class can only be loaded by sun.reflect.DelegatingClassLoader", bizIdentity, name));
* }
*
* // 1. findLoadedClass 查看{当前类加载器}是否已经加载过
* if (clazz == null) {
* clazz = findLoadedClass(name);
* {
* @see java.lang.ClassLoader#findLoadedClass(java.lang.String)
* }
* }
*
* // 2. JDK related class 解析的是jdk的类 【即:尝试使用{jdk类加载器}加载类】
* // 加载"java.home"路径下的jar包的类,父类加载器是extClassLoader。
* // 使用的还是递归机制 !!! 所以,如果被加载了extClassLoader,那么子类加载器,就必须共用类,做不到隔离功能。
* if (clazz == null) {
* clazz = resolveJDKClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveJDKClass(java.lang.String)
* // !!! JDKDelegateClassLoader 的初始化,见 {@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#init()}
* @see com.alipay.sofa.ark.container.service.classloader.JDKDelegateClassLoader#loadClass(java.lang.String)
* }
* }
*
* // 3. Ark Spi class 内置的类 【即:尝试使用{ContainerClassLoader}加载类】
* if (clazz == null) {
* clazz = resolveArkClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveArkClass(java.lang.String)
* // !!! classloaderService.getArkClassLoader() == arkClassLoader ==== ContainerClassLoader 容器级别的类加载器
* // !!! arkClassLoader 的初始化 {@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#init()}
* if (classloaderService.isArkSpiClass(name) // "com.alipay.sofa.ark.spi"
* || classloaderService.isArkApiClass(name) // "com.alipay.sofa.ark.api"
* || classloaderService.isArkLogClass(name) // "com.alipay.sofa.ark.common.log"
* || classloaderService.isArkExceptionClass(name) // "com.alipay.sofa.ark.exception"
* ) {
* try {
* return classloaderService.getArkClassLoader().loadClass(name);
* } catch (ClassNotFoundException e) {
* // ignore
* }
* }
* return null;
* }
* }
*
* // 4. pre find class 前置操作【即:尝试使用{hook级别类{前置}加载器}加载类】
* if (clazz == null) {
* clazz = preLoadClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.BizClassLoader#preLoadClass(java.lang.String)
* // 获取spi文件com.alipay.sofa.ark.spi.service.classloader.ClassLoaderHook中,key为biz-classloader-hook的配置
* }
* }
*
* // 5. Plugin Export class 【即:尝试使用{plugin级别类加载器}加载类】
* if (clazz == null) {
* clazz = resolveExportClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveExportClass(java.lang.String)
* boolean shouldFindExportedClass = shouldFindExportedClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.BizClassLoader#shouldFindExportedClass(java.lang.String className)
* // bizIdentity === "alipay-sofaark-biz:1.0-SNAPSHOT";
*
* // 不是{拒绝导入}的类
* return !classloaderService.isDeniedImportClass(bizIdentity, className);
* {
* @see com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#isDeniedImportClass(java.lang.String, java.lang.String)
* // 获取{业务模块}对象
* Biz biz = bizManagerService.getBizByIdentity(bizIdentity);
* if (biz == null) {
* return false;
* }
*
* // xxx-ark-biz.jar的pom.xml中配置的,命中类规则
* for (String pattern : biz.getDenyImportClasses()) {
* if (pattern.equals(className)) {
* return true;
* }
* }
*
* // xxx-ark-biz.jar的pom.xml中配置的,命中包规则
* String pkg = ClassUtils.getPackageName(className);
* for (String pattern : biz.getDenyImportPackageNodes()) {
* if (pkg.equals(pattern)) {
* return true;
* }
* }
*
* // xxx-ark-biz.jar的pom.xml中配置的,命中包规则
* for (String pattern : biz.getDenyImportPackageStems()) {
* if (pkg.startsWith(pattern)) {
* return true;
* }
* }
*
* return false;
* }
* }
*
* // 不是{拒绝导入}的类,那么使用{plugin级别的类加载器}尝试加载
* if (shouldFindExportedClass) {
* ClassLoader importClassLoader = classloaderService.findExportClassLoader(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#findExportClassLoader(java.lang.String)
* // 类的加载器
* // exportClassAndClassLoaderMap,居于{插件的Manifest}进行初始化,见 {@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#prepareExportClassAndResourceCache()}
* ClassLoader exportClassLoader = exportClassAndClassLoaderMap.get(className);
*
* // 包的加载器
* String packageName = ClassUtils.getPackageName(className);
* if (exportClassLoader == null) {
* // exportNodeAndClassLoaderMap,居于{插件的Manifest}进行初始化,见 {@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#prepareExportClassAndResourceCache()}
* exportClassLoader = exportNodeAndClassLoaderMap.get(packageName);
* }
*
* // 包的加载器
* while (!Constants.DEFAULT_PACKAGE.equals(packageName) && exportClassLoader == null) {
* // exportStemAndClassLoaderMap,居于{插件的Manifest}进行初始化,见 {@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#prepareExportClassAndResourceCache()}
* exportClassLoader = exportStemAndClassLoaderMap.get(packageName);
* packageName = ClassUtils.getPackageName(packageName);
* }
* return exportClassLoader;
* }
* if (importClassLoader != null) {
* try {
* return importClassLoader.loadClass(name);
* } catch (ClassNotFoundException e) {
* // just log when debug level
* if (ArkLoggerFactory.getDefaultLogger().isDebugEnabled()) {
* // log debug message
* ArkLoggerFactory.getDefaultLogger().debug("Fail to load export class " + name, e);
* }
* }
* }
* }
* return null;
* }
* }
*
* // 6. Biz classpath class 业务类加载器【即:尝试使用{当前类加载器}加载类】
* if (clazz == null) {
* clazz = resolveLocalClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveLocalClass(java.lang.String)
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
* }
* }
*
* // 7. Java Agent ClassLoader for agent problem,
* // agent类加载器,即:"-javaagent:"声明的路径 【即:尝试使用{agent的类加载器}加载类】
* if (clazz == null) {
* clazz = resolveJavaAgentClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveJavaAgentClass(java.lang.String)
* try {
* // agentClassLoader 实例化,见 {@link com.alipay.sofa.ark.container.service.classloader.ClassLoaderServiceImpl#createAgentClassLoader()}
* classloaderService.getAgentClassLoader().loadClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AgentClassLoader#loadClass(java.lang.String)
* }
*
* return classloaderService.getSystemClassLoader().loadClass(name);
* {
* // 系统(app)类加载器加载
* }
* } catch (ClassNotFoundException e) {
* // ignore
* }
* return null;
* }
* }
*
* // 8. post find class 后置操作【即:尝试使用{hook级别的{后置}类加载器}加载类】
* if (clazz == null) {
* clazz = postLoadClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.BizClassLoader#postLoadClass(java.lang.String)
* }
* }
*
* // 解析类
* if (clazz != null) {
* if (resolve) {
* super.resolveClass(clazz);
* {
* @see java.lang.ClassLoader#resolveClass(java.lang.Class)
* }
* }
* return clazz;
* }
*
* throw new ArkLoaderException(String.format("[ArkBiz Loader] %s : can not load class: %s", bizIdentity, name));
* }
*
* @see com.alipay.sofa.ark.container.service.classloader.PluginClassLoader#loadClassInternal(java.lang.String name, boolean)
* }
*
*/
.
/**
*
*
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#loadClass(java.lang.String name, boolean)
* {
* @see com.alipay.sofa.ark.container.service.classloader.PluginClassLoader#loadClassInternal(java.lang.String, boolean)
* Class clazz = null;
*
* // 0. sun reflect related class throw exception directly【即:检查是否是{sun类}】
* if (classloaderService.isSunReflectClass(name)) {
* throw new ArkLoaderException(String.format(
* "[ArkPlugin Loader] %s : can not load class: %s, this class can only be loaded by sun.reflect.DelegatingClassLoader", pluginName, name));
* }
*
* // 1. findLoadedClass 查看{当前类加载器}是否已经加载过
* if (clazz == null) {
* clazz = findLoadedClass(name);
* }
*
* // 2. JDK related class 解析的是jdk的类 【即:尝试使用{jdk类加载器}加载类】
* // 加载"java.home"路径下的jar包的类,父类加载器是extClassLoader。
* // 使用的还是递归机制 !!! 所以,如果被加载了extClassLoader,那么子类加载器,就必须共用类,做不到隔离功能。
* if (clazz == null) {
* clazz = resolveJDKClass(name);
* }
*
* // 3. Ark Spi class 内置的类 【即:尝试使用{ContainerClassLoader}加载类】
* if (clazz == null) {
* clazz = resolveArkClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveArkClass(java.lang.String)
* // !!! classloaderService.getArkClassLoader() == arkClassLoader ==== ContainerClassLoader 容器级别的类加载器
* }
* }
*
* // 4. pre find class 前置操作【即:尝试使用{hook级别{前置}类加载器}加载类】
* if (clazz == null) {
* clazz = preLoadClass(name);
* }
*
* // 5. Import class export by other plugins 【即:尝试使用{plugin级别类加载器}加载类】,即:有其他plugin加载
* if (clazz == null) {
* clazz = resolveExportClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveExportClass(java.lang.String)
* }
* }
*
* // 6. Plugin classpath class 【即:尝试使用{当前类加载器}加载类】
* if (clazz == null) {
* clazz = resolveLocalClass(name);
* {
* @see com.alipay.sofa.ark.container.service.classloader.AbstractClasspathClassLoader#resolveLocalClass(java.lang.String)
* try {
* return super.loadClass(name, false);
* } catch (ClassNotFoundException e) {
* // ignore
* }
* return null;
* }
* }
*
* // 7. Java Agent ClassLoader for agent problem
* // agent类加载器,即:"-javaagent:"声明的路径 【即:尝试使用{agent的类加载器}加载类】
* if (clazz == null) {
* clazz = resolveJavaAgentClass(name);
* }
*
* // 8. Post find class 后置操作【即:尝试使用{hook级别的{后置}类加载器}加载类】
* if (clazz == null) {
* clazz = postLoadClass(name);
* }
*
* // 解析类
* if (clazz != null) {
* if (resolve) {
* super.resolveClass(clazz);
* }
* return clazz;
* }
*
* throw new ArkLoaderException(String.format("[ArkPlugin Loader] %s : can not load class: %s", pluginName, name));
* }
*
*/