写前言之前-->说说基于jdk实现的spi如何结合spring实现依赖注入。在本文的demo中使用了动态代理,在调试的过程中发现了一个神奇的现象。如下图,代理对象变为null,但是不会出现空指针异常。首先看一下示例代理的核心实现逻辑对象结果=空;如果(canPass){结果=method.invoke(目标,args);完成后(方法,参数);}返回结果;一片空白。这个想法使调试成为可能。调用对象时,默认会调用toString方法。当proxy触发invoke时,由于preHandle找不到toString方法,会导致canPass为false,从而触发null现象。我们可以验证我们没有代理的证据。@Override下调整核心方法publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{if("toString".equals(method.getName())){return"我是toString方法";}booleancanPass=preHandle(method,args);对象结果=空;如果(canPass){结果=method.invoke(目标,args);完成后(方法,参数);}返回结果;图解问题修复1.方法一:禁用idea2的默认调用toString方法方法二:在代理invoke方法中,添加如下代码片段//如果Object方法直接反射调用if(Object.class.equals(method.getDeclaringClass())){returnmethod.invoke(this,args);}这种方案,mybatis中实现的动态代理有@OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{try{if(Object.class.equals(method.getDeclaringClass())){返回方法。调用柯(这个,参数);}elseif(method.isDefault()){if(privateLookupInMethod==null){returninvokeDefaultMethodJava8(proxy,method,args);}else{returninvokeDefaultMethodJava9(proxy,method,args);}}}catch(Throwablet){throwExceptionUtil.unwrapThrowable(t);}finalMapperMethodmapperMethod=cachedMapperMethod(方法);返回mapperMethod.execute(sqlSession,args);查看更多源代码
