.
各种类加载器 & 优先级
/*** <pre>* 类加载器的使用优先级(由高到底)* 0、JDKDelegateClassLoader* 1、ContainerClassLoader* 2、hook级别类{前置}加载器* 3、PluginClassLoader* 4、BizClassLoader(当前类加载器)* 5、AgentClassLoader、systemClassLoader* 6、hook级别的{后置}类加载器* </pre>** <pre>* 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}领域的类** BizClassLoader* 继承:没有父类加载器* 实例化在:{@link com.alipay.sofa.ark.container.service.biz.BizFactoryServiceImpl#createBiz(com.alipay.sofa.ark.spi.archive.BizArchive)}* 用途:用于加载{业务}领域的类** PluginClassLoader* 继承:没有父类加载器* 实例化在:{@link com.alipay.sofa.ark.container.service.plugin.PluginFactoryServiceImpl#createPlugin(com.alipay.sofa.ark.spi.archive.PluginArchive)}* 用途:用于加载{插件}领域的类* </pre>*/
.
BizClassLoader
/*** <pre>* @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)* }* </pre>*/
.
PluginClassLoader
/**** <pre>* @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));* }* </pre>*/