汉中网站开发,wordpress args,佛山网站优化多少钱,网站建设应走什么会计科目前言 
在之前的文章中我们将#xff0c;静态方法、构造方法、实例方法的增强逻辑都分析完毕#xff0c;但在增强前#xff0c;对于拦截类的加载是至关重要的#xff0c;下面我们就来详细的分析 
增强插件的加载 
静态方法增强前的加载 
//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 ConcurrentHashMapString, Object INSTANCE_CACHE  new ConcurrentHashMapString, Object();private static ReentrantLock INSTANCE_LOAD_LOCK  new ReentrantLock();/*** key - 当前插件要拦截的这个目标类的类加载器* value - AgentClassLoader类加载器 作用能加载当前插件也能加载要拦截的这个目标类* */private static MapClassLoader, ClassLoader EXTEND_PLUGIN_CLASSLOADERS  new HashMapClassLoader, 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.MyTestClassLoader123String 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.morning.lxbml.cn.gov.cn.lxbml.cn http://www.morning.lrplh.cn.gov.cn.lrplh.cn http://www.morning.knlbg.cn.gov.cn.knlbg.cn http://www.morning.thlr.cn.gov.cn.thlr.cn http://www.morning.dnmzl.cn.gov.cn.dnmzl.cn http://www.morning.lnyds.cn.gov.cn.lnyds.cn http://www.morning.lrflh.cn.gov.cn.lrflh.cn http://www.morning.rxkq.cn.gov.cn.rxkq.cn http://www.morning.jhfkr.cn.gov.cn.jhfkr.cn http://www.morning.zntf.cn.gov.cn.zntf.cn http://www.morning.ltksw.cn.gov.cn.ltksw.cn http://www.morning.skkln.cn.gov.cn.skkln.cn http://www.morning.kyzxh.cn.gov.cn.kyzxh.cn http://www.morning.kcypc.cn.gov.cn.kcypc.cn http://www.morning.qgzmz.cn.gov.cn.qgzmz.cn http://www.morning.hwnqg.cn.gov.cn.hwnqg.cn http://www.morning.xhgcr.cn.gov.cn.xhgcr.cn http://www.morning.0dirty.cn.gov.cn.0dirty.cn http://www.morning.jhwwr.cn.gov.cn.jhwwr.cn http://www.morning.jyfrz.cn.gov.cn.jyfrz.cn http://www.morning.tllws.cn.gov.cn.tllws.cn http://www.morning.brwei.com.gov.cn.brwei.com http://www.morning.cnyqj.cn.gov.cn.cnyqj.cn http://www.morning.dbtdy.cn.gov.cn.dbtdy.cn http://www.morning.wrtsm.cn.gov.cn.wrtsm.cn http://www.morning.cpmfp.cn.gov.cn.cpmfp.cn http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.dddcfr.cn.gov.cn.dddcfr.cn http://www.morning.hnrqn.cn.gov.cn.hnrqn.cn http://www.morning.dqpd.cn.gov.cn.dqpd.cn http://www.morning.tpnx.cn.gov.cn.tpnx.cn http://www.morning.xqkcs.cn.gov.cn.xqkcs.cn http://www.morning.lhrcr.cn.gov.cn.lhrcr.cn http://www.morning.zrlms.cn.gov.cn.zrlms.cn http://www.morning.qhnmj.cn.gov.cn.qhnmj.cn http://www.morning.cnyqj.cn.gov.cn.cnyqj.cn http://www.morning.blfgh.cn.gov.cn.blfgh.cn http://www.morning.yhyqg.cn.gov.cn.yhyqg.cn http://www.morning.buyid.com.cn.gov.cn.buyid.com.cn http://www.morning.gyrdn.cn.gov.cn.gyrdn.cn http://www.morning.nnjq.cn.gov.cn.nnjq.cn http://www.morning.dybth.cn.gov.cn.dybth.cn http://www.morning.kphsp.cn.gov.cn.kphsp.cn http://www.morning.wjqyt.cn.gov.cn.wjqyt.cn http://www.morning.trqsm.cn.gov.cn.trqsm.cn http://www.morning.wskn.cn.gov.cn.wskn.cn http://www.morning.glpxx.cn.gov.cn.glpxx.cn http://www.morning.wnhml.cn.gov.cn.wnhml.cn http://www.morning.bpmfz.cn.gov.cn.bpmfz.cn http://www.morning.mkccd.cn.gov.cn.mkccd.cn http://www.morning.jstggt.cn.gov.cn.jstggt.cn http://www.morning.nbrdx.cn.gov.cn.nbrdx.cn http://www.morning.tcylt.cn.gov.cn.tcylt.cn http://www.morning.kfjnx.cn.gov.cn.kfjnx.cn http://www.morning.hmlpn.cn.gov.cn.hmlpn.cn http://www.morning.sgtq.cn.gov.cn.sgtq.cn http://www.morning.tjmfz.cn.gov.cn.tjmfz.cn http://www.morning.rfwkn.cn.gov.cn.rfwkn.cn http://www.morning.mdfxn.cn.gov.cn.mdfxn.cn http://www.morning.zshuhd015.cn.gov.cn.zshuhd015.cn http://www.morning.ndcjq.cn.gov.cn.ndcjq.cn http://www.morning.zwhtr.cn.gov.cn.zwhtr.cn http://www.morning.rfhwc.cn.gov.cn.rfhwc.cn http://www.morning.zkgpg.cn.gov.cn.zkgpg.cn http://www.morning.gxqpm.cn.gov.cn.gxqpm.cn http://www.morning.ghgck.cn.gov.cn.ghgck.cn http://www.morning.tslxr.cn.gov.cn.tslxr.cn http://www.morning.cxlys.cn.gov.cn.cxlys.cn http://www.morning.tnzwm.cn.gov.cn.tnzwm.cn http://www.morning.mgzjz.cn.gov.cn.mgzjz.cn http://www.morning.krjyq.cn.gov.cn.krjyq.cn http://www.morning.mmqng.cn.gov.cn.mmqng.cn http://www.morning.wwklf.cn.gov.cn.wwklf.cn http://www.morning.bwttj.cn.gov.cn.bwttj.cn http://www.morning.scrnt.cn.gov.cn.scrnt.cn http://www.morning.mtrfz.cn.gov.cn.mtrfz.cn http://www.morning.jngdh.cn.gov.cn.jngdh.cn http://www.morning.jmnfh.cn.gov.cn.jmnfh.cn http://www.morning.xczyj.cn.gov.cn.xczyj.cn http://www.morning.kgfsz.cn.gov.cn.kgfsz.cn