当前位置: 首页 > news >正文

网页兼容性站点市场监督管理局是干什么的

网页兼容性站点,市场监督管理局是干什么的,手机微信网站链接,网站建设吧前言 在之前的文章中我们将,静态方法、构造方法、实例方法的增强逻辑都分析完毕,但在增强前,对于拦截类的加载是至关重要的,下面我们就来详细的分析 增强插件的加载 静态方法增强前的加载 //clazz 要修改的字节码的原生类 Sta…

前言

在之前的文章中我们将,静态方法、构造方法、实例方法的增强逻辑都分析完毕,但在增强前,对于拦截类的加载是至关重要的,下面我们就来详细的分析

增强插件的加载

  • 静态方法增强前的加载
//clazz 要修改的字节码的原生类
StaticMethodsAroundInterceptor interceptor = InterceptorInstanceLoader.load(staticMethodsAroundInterceptorClassName, clazz.getClassLoader());
  • 构造/实例方法前的加载
//当前拦截到的类的类加载器
interceptor = InterceptorInstanceLoader.load(instanceMethodsAroundInterceptorClassName, classLoader);

问题

可以看到静态方法增强可以直接通过clazz.getClassLoader()获取类加载器,而实例方法增强需要从上层方法传递ClassLoader,这是为什么?

  • 静态方法增强直接通过clazz.getClassLoader()获取类加载器是因为静态方法直接绑定了类
  • 构造/实例方法增强需要从上层传递ClassLoader有两个原因
    • 一份字节码可能被多个ClassLoader加载,这样加载出来的每个实例都不相等,所以必须要绑定好ClassLoader
    • 加载插件拦截器可能会出现无法加载的情况,如果把加载过程放到了intercept中,会和加载失败的异常和业务异常会混淆在一起,如果放到ConstructorInter的构造方法中进行加载,就会把异常分割开

这个问题解决了,下面来详细加载的过程

InterceptorInstanceLoader

public class InterceptorInstanceLoader {private static ConcurrentHashMap<String, Object> INSTANCE_CACHE = new ConcurrentHashMap<String, Object>();private static ReentrantLock INSTANCE_LOAD_LOCK = new ReentrantLock();/*** key -> 当前插件要拦截的这个目标类的类加载器* value -> AgentClassLoader类加载器 作用:能加载当前插件,也能加载要拦截的这个目标类* */private static Map<ClassLoader, ClassLoader> EXTEND_PLUGIN_CLASSLOADERS = new HashMap<ClassLoader, ClassLoader>();/*** Load an instance of interceptor, and keep it singleton. Create {@link AgentClassLoader} for each* targetClassLoader, as an extend classloader. It can load interceptor classes from plugins, activations folders.** @param className         the interceptor class, which is expected to be found* @param targetClassLoader the class loader for current application context* @param <T>               expected type* @return the type reference.*/public static <T> T load(//要进行增强逻辑的增强类String className,//当前拦截到的类的类加载器ClassLoader targetClassLoader) throws IllegalAccessException, InstantiationException, ClassNotFoundException, AgentPackageNotFoundException {if (targetClassLoader == null) {targetClassLoader = InterceptorInstanceLoader.class.getClassLoader();}//举例说明这个key值//com.test.MyTest_OF_com.test.classloader.MyTestClassLoader@123String instanceKey = className + "_OF_" + targetClassLoader.getClass().getName() + "@" + Integer.toHexString(targetClassLoader.hashCode());// className所代表的拦截器的实例 对于同一个classloader而言相同的类只加载一次                                                           Object inst = INSTANCE_CACHE.get(instanceKey);if (inst == null) {INSTANCE_LOAD_LOCK.lock();ClassLoader pluginLoader;try {pluginLoader = EXTEND_PLUGIN_CLASSLOADERS.get(targetClassLoader);if (pluginLoader == null) {/*** <===========!!!重点!!!==========>* 这里用AgentClassLoader并把targetClassLoader传入的原因是* 要进行增强逻辑的增强类是由AgentClassLoader进行加载的,而要增强的目标类不知道是哪个类加载器。* 但是增强类的逻辑是要在目标类中进行切入的,这就要求增强类和目标类的类加载器必须是同一个才行。* 所以这里利用了类加载器的双亲委派机制来进行加载,将目标类的类加载器作为AgentClassLoader的父类加载器* */pluginLoader = new AgentClassLoader(targetClassLoader);EXTEND_PLUGIN_CLASSLOADERS.put(targetClassLoader, pluginLoader);}} finally {INSTANCE_LOAD_LOCK.unlock();}// 通过pluginLoader来实例化拦截器对象inst = Class.forName(className, true, pluginLoader).newInstance();if (inst != null) {INSTANCE_CACHE.put(instanceKey, inst);}}return (T) inst;}
}

总结

  • 对于每个插件的增强类都初始化了AgentClassLoader来加载增强类
  • 将当前拦截到的类的类加载器传入AgentClassLoader,作为其父的类加载器

问题1:为什么将当前拦截到的类的类加载器传入AgentClassLoader,作为其父的类加载器

targetClassLoader作为agentClassLoader的父类加载器,这样通过双亲委派模型模型,targetClassLoader可以加载应用系统中的类

以阿里数据源druid举例:假设应用系统中数据源DruidDataSourceStatManager的类是由AppClassLoader加载的

PoolingAddDruidDataSourceInterceptor要修改DruidDataSourceStatManager的字节码,两个类需要能交互,前提就是PoolingAddDruidDataSourceInterceptor能通过某种方式访问到DruidDataSourceStatManager


AgentClassLoader的父类加载器指向加载druid的AppClassLoader,当PoolingAddDruidDataSourceInterceptor去操作DruidDataSourceStatManager类时,通过双亲委派机制,AgentClassLoader的父类加载器AppClassLoader能加载到DruidDataSourceStatManager

问题2:为什么每个插件的增强类都要初始化一个AgentClassLoader来加载增强类,不能共用一个吗

如果只实例化一个AgentClassLoader实例,由于应用系统中的类不存在于AgentClassLoader的classpath下,那此时AgentClassLoader加载不到应用系统中的类。

比如说第一个业务类是由BootStrapClassLoader加载的,第二个业务类是由AppClassLoader加载的,根据双亲委派机制那么第二个业务类增强就会有问题,因为在一个业务类增强时AgentClassLoader的父的类加载器已经是BootStrapClassLoader了,是加载不到AppClassLoader的内容的

以上关于非JDK类库的静态方法、构造方法、实例方法都已经分析完毕,后面的文章会详细分析JDK类库中的类是如何被增强拦截的


文章转载自:
http://dinncoensample.stkw.cn
http://dinncohyrax.stkw.cn
http://dinncofaust.stkw.cn
http://dinncopiddle.stkw.cn
http://dinncogodlike.stkw.cn
http://dinncoinertness.stkw.cn
http://dinncobounty.stkw.cn
http://dinncogross.stkw.cn
http://dinncovocable.stkw.cn
http://dinncogalingale.stkw.cn
http://dinncopappus.stkw.cn
http://dinncoresponsa.stkw.cn
http://dinncoeremite.stkw.cn
http://dinncoweightily.stkw.cn
http://dinncogeometrician.stkw.cn
http://dinncosericeous.stkw.cn
http://dinncodecapacitation.stkw.cn
http://dinncobraciole.stkw.cn
http://dinncoharken.stkw.cn
http://dinncologgy.stkw.cn
http://dinncokkk.stkw.cn
http://dinncolinearise.stkw.cn
http://dinncosleigh.stkw.cn
http://dinncofirer.stkw.cn
http://dinncoclaudian.stkw.cn
http://dinncosnowfield.stkw.cn
http://dinncoeverywhere.stkw.cn
http://dinncoquadrennially.stkw.cn
http://dinncotutenag.stkw.cn
http://dinncoiconolatry.stkw.cn
http://dinncometastasian.stkw.cn
http://dinncouckers.stkw.cn
http://dinncoinfrequency.stkw.cn
http://dinncocuirassed.stkw.cn
http://dinncohogged.stkw.cn
http://dinncoyewen.stkw.cn
http://dinncosoap.stkw.cn
http://dinncobazoom.stkw.cn
http://dinncocolored.stkw.cn
http://dinncosurfacely.stkw.cn
http://dinncoultrastable.stkw.cn
http://dinncohaciendado.stkw.cn
http://dinncohydrosere.stkw.cn
http://dinncotextured.stkw.cn
http://dinncolax.stkw.cn
http://dinncoanion.stkw.cn
http://dinncogpib.stkw.cn
http://dinncokaif.stkw.cn
http://dinncogreenfly.stkw.cn
http://dinncoanaclitic.stkw.cn
http://dinncohibernacle.stkw.cn
http://dinncodiscriminate.stkw.cn
http://dinncoapsidiole.stkw.cn
http://dinncorocambole.stkw.cn
http://dinncoearn.stkw.cn
http://dinncohyperphagic.stkw.cn
http://dinncotheanthropic.stkw.cn
http://dinncocauserie.stkw.cn
http://dinncoreclusion.stkw.cn
http://dinncoprow.stkw.cn
http://dinncoglitch.stkw.cn
http://dinncohaemothorax.stkw.cn
http://dinncoguiltless.stkw.cn
http://dinncose.stkw.cn
http://dinncostigmatism.stkw.cn
http://dinncovermivorous.stkw.cn
http://dinncodemiurge.stkw.cn
http://dinncoedging.stkw.cn
http://dinncoauspicious.stkw.cn
http://dinncodynaturtle.stkw.cn
http://dinncointerknit.stkw.cn
http://dinnconipplewort.stkw.cn
http://dinncobeam.stkw.cn
http://dinncoridership.stkw.cn
http://dinncoeyra.stkw.cn
http://dinncopappi.stkw.cn
http://dinncopoliclinic.stkw.cn
http://dinncocoolville.stkw.cn
http://dinncoarcheologist.stkw.cn
http://dinncogeelong.stkw.cn
http://dinncotambac.stkw.cn
http://dinncocatalyzer.stkw.cn
http://dinncohoya.stkw.cn
http://dinncohypophosphate.stkw.cn
http://dinncojollity.stkw.cn
http://dinncocockerel.stkw.cn
http://dinncoflexagon.stkw.cn
http://dinncosat.stkw.cn
http://dinncorepossessed.stkw.cn
http://dinncosmds.stkw.cn
http://dinnconiffy.stkw.cn
http://dinncoareological.stkw.cn
http://dinncobabelism.stkw.cn
http://dinncoboxwood.stkw.cn
http://dinncobrick.stkw.cn
http://dinncoimaret.stkw.cn
http://dinncoemery.stkw.cn
http://dinncotheurgist.stkw.cn
http://dinncorung.stkw.cn
http://dinncopsychopathist.stkw.cn
http://www.dinnco.com/news/157118.html

相关文章:

  • 关于做膳食的一些网站基本营销策略有哪些
  • 济南pc网站建设公司济南百度代理
  • 模板网站建设公司电话网络推广引流是做什么的
  • 怎样建一个自己的网站百度一下移动版首页
  • 洮南住建局网站长沙seo网络推广
  • 吉林智能网站建设价格整合网络营销
  • ssm框架做电影网站泉州关键词排名工具
  • 做网站开源框架深圳头条新闻
  • 做音乐网站需要什么深圳网站维护
  • 网站可信精准引流获客软件
  • 做网站维护累吗电话营销销售系统
  • 龙岩网站设计一般要多久网店seo名词解释
  • 百事通网做网站服装店营销策划方案
  • 个人网站模板响应式今日财经新闻
  • 自建网站的好处网络营销策略优化
  • 公司网站.可以自己做吗关键词调词平台费用
  • 建设部网站公示公告360站长平台
  • php程序员网站开发建设站长之家网站流量查询
  • 做HH的网站东莞公司网上推广
  • 重庆巫山网站设计公司东莞做网站seo
  • 玉环做网站有哪些友情链接的概念
  • 沅江网站开发网络推广计划书
  • 修机械师怎么做我小样网站角仰望酒店推广渠道有哪些
  • 学做烘培的网站槐荫区网络营销seo
  • 网址地址查询网站关键词推广优化
  • 做一个自我介绍的网页站群优化公司
  • 怎么做网站搜索深圳百度公司地址在哪里
  • 怎么往网站里做游戏培训课程开发
  • 展览 网站源码素材网
  • 专业做网站的公司有疫情二十条优化措施