由于最近在做的分布式爬虫中用到了 XXL-GLUE
来动态执行抓取脚本。由于抓取脚本较多,想着针对一些通用操作比如存库封装了父类CrawlerWorker
,并且由 CrawlerWorker
实现了GlueHandler
接口。
然后由KaguraScript extends CrawlerWorker
然后直接在 KaguraScript
中直接使用父类 CrawlerWorker
中的duplicateKeyDao
,但是它居然是null
。
虽然GlueFactory
中injectService
方法会在反射后注入@Resource
跟@Autowired
的字段,但 injectService
方法是通过instance.getClass().getDeclaredFields();
显然问题在这, getDeclaredFields
方法无法获取从父类继承的属性。
找到了问题我们该如何解决呢, 其实我们只需要把com.xxl.glue.core.GlueFactory.java
类中injectService
方法第76行的getDeclaredFields()
改为getFields()
即可,这时就该instrument()
登场了,直接上代码:
ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
//替换原GlueFactory.java中第76行getDeclaredFields()为getFields(),不然父类@Autowired无法注入
String methadName = "injectService";
CtClass glueFactory = classPool.get("com.xxl.glue.core.GlueFactory");
CtMethod injectService = glueFactory.getDeclaredMethod(methadName);
injectService.instrument(
new ExprEditor() {
public void edit(MethodCall m) throws CannotCompileException {
if (m.getMethodName().equals("getDeclaredFields")) {
m.replace("{" +
"$_ = $0.getFields();" +
"}");
}
}
});
glueFactory.toClass();
未经允许不得转载:鹞之神乐 » javassist instrument()方法实战