bytebuddy对于final类的增强


尝试对Spring里的一个 类进行增强,使用了bytebuddy进行增强。但是一直不成功。 最后发现这个类是final类,把排查过程记录如下:

第一步:尝试用bytebuddy对Spring的类进行增强,一直不成功,并且基于Spring的应用启动报错。

第二步:打开bytebuddy的调试功能,并注册到Agent上:

// 声明Listener
AgentBuilder.Listener listener = new AgentBuilder.Listener() {

	@Override
	public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
	}

	@Override
	public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded, DynamicType dynamicType) {
		logger.info("transformation:" + typeDescription.getSimpleName());
		try {
			dynamicType.toJar(new File("./dumpbuddy.jar"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onIgnored(TypeDescription typeDescription, ClassLoader classLoader, JavaModule module, boolean loaded) {

	}

	@Override
	public void onError(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded, Throwable throwable) {
		logger.error("handle type:" + typeName + " error");
	}

	@Override
	public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
	}
};
//注册listener
new AgentBuilder.Default()
	.type(named("org.springframework.context.support.AbstractApplicationContext"))
	.transform(new AgentBuilder.Transformer() {
		@Override
		public DynamicType.Builder<?> transform(
				DynamicType.Builder<?> builder, TypeDescription typeDescription,
				ClassLoader classLoader, JavaModule module) {
			//xxxxxxx
		}
	}).with(listener).installOn(instrumentation);

此时再启动被增强应用,在被增强应用的目录下,会产生一个 dumpbuddy.jar的文件,里面是刚刚被增强的类的基本信息。使用jd-gui.exe 这种工具可以反编译查看。

此时查看,发现增强部分的函数,只剩下一行了。 而且看起来明显功能不全。 经过查阅google, 说是bytebuddy 会遵循java的规范,对于final类,无法进行subclass的处理,此部分如果确实需要处理,需要使用javaassist等方式,人工处理字节码,去掉final的修饰符。