当前位置: 首页 > 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://www.yayakq.cn/news/222926/

相关文章:

  • 做网站面临的困难长春建筑学院
  • 罗湖做网站公司排名公司官网怎么做
  • 百度商桥绑定网站安卓手机软件开发平台
  • 趴比库的网站是谁建设的wordpress 去掉头部
  • 蓝海基业做的网站好吗logo在线制作设计
  • 山东网站空间网站内容建设流程
  • 苏州网站设计公司排名做网站需多少钱
  • 学做网站 书企业网站的基本内容和营销功能
  • asp网站上一篇下一篇代码微商引流的最快方法是什么
  • 建设银行假网站泰安房产网签数据汇总
  • 电子商务网站有哪些内容网站建设兆金手指科杰
  • 深圳酒店网站建设花都网站建设设计
  • 沙河市建设局网站看到一个电商网站帮做淘宝
  • wix做网站手机乱了网站首页轮播怎么做
  • 企业手机端网站源码下载wordpress 乱码
  • 地方网站系统重庆綦江网站制作公司电话
  • diy科技制作网站网站建设公司税负率
  • 做网站需要用什么系统采购
  • 江西省楚天建设集团有限公司网站钓鱼网站制作
  • 讯杰网站建设星巴克网站建设ppt
  • 好看的网站 你知道的2021网站建设费能不能认定为广告费
  • 企业为啥要做网站建设一个网站的步骤有哪些
  • 网站建设及制作企业开办网站
  • 系部网站建设创新点页面设计合同模板
  • 在线装修设计网站网站优化的链接建设
  • 网站建设公司怎样选怎么注销网站备案
  • 免费psd模板网站eclipse jsp 网站开发
  • 分析可口可乐网站建设的目的百度推广 个人网站
  • 众筹网站开发推广费用一般多少
  • 做网站卖水果哪里进货企业网站设计