-
-
Notifications
You must be signed in to change notification settings - Fork 829
Open
Labels
Description
when i try to intercept all http request,comes error:IllegalArgumentException
but seems my method is being found and method prarms is right.
i use java 8 version and bytebuddy 1.17.6 version
starter:
@Slf4j
@SpringBootApplication
@ComponentScan("config")
public class Main {
public static void main(String[] args) throws Exception {
Instrumentation instrumentation = ByteBuddyAgent.install();
new AgentBuilder.Default()
// 允许重新定义类
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.with(new AgentBuilder.Listener() {
@Override
public void onDiscovery(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
log.debug("🔍 发现类: {}", typeName);
}
@Override
public void onTransformation(TypeDescription typeDescription, ClassLoader classLoader,
JavaModule module, boolean loaded, DynamicType dynamicType) {
log.info("🔨 转换类: {}", typeDescription.getActualName());
try {
// ⭐ 保存增强后的字节码到文件
String fileName = typeDescription.getSimpleName() + "_Enhanced.class";
File outputDir = new File("enhanced-classes");
if (!outputDir.exists()) {
outputDir.mkdirs();
}
File classFile = new File(outputDir, fileName);
dynamicType.saveIn(outputDir);
log.info("💾 增强后的字节码已保存到: {}", classFile.getAbsolutePath());
} catch (IOException e) {
log.error("❌ 保存字节码文件失败", e);
}
}
@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) {
log.error("❌ 转换类失败: {}", typeName, throwable);
}
@Override
public void onComplete(String typeName, ClassLoader classLoader, JavaModule module, boolean loaded) {
log.debug("✅ 完成转换: {}", typeName);
}
})
.type((ElementMatchers.isAnnotatedWith(RestController.class)
.or(ElementMatchers.isAnnotatedWith(Controller.class)))
.and(ElementMatchers.not(ElementMatchers.nameStartsWith("org.springframework")))
.and(ElementMatchers.not(ElementMatchers.nameStartsWith("org.springframework")))
)
.transform((builder, type, classLoader, module, protectionDomain) -> {
return builder
.method(ElementMatchers.isAnnotatedWith(RequestMapping.class)
.or(ElementMatchers.isAnnotatedWith(GetMapping.class))
.or(ElementMatchers.isAnnotatedWith(PostMapping.class))
.or(ElementMatchers.isAnnotatedWith(PutMapping.class))
.or(ElementMatchers.isAnnotatedWith(DeleteMapping.class))
.or(ElementMatchers.isAnnotatedWith(PatchMapping.class)))
.intercept(MethodDelegation.to(Interceptor.class)
);
})
.installOn(instrumentation);
SpringApplication.run(Main.class, args);
}
interceptor:
public class Interceptor {
@RuntimeType //将返回值转换成具体的方法返回值类型,加了这个注解 intercept 方法才会被执行
public static Object intercept(
// 被拦截的目标对象 (动态生成的目标对象)
@This Object target,
// 正在执行的方法Method 对象(目标对象父类的Method)
@Origin Method method,
// 正在执行的方法的全部参数
@AllArguments Object[] arguments,
// 目标对象的一个代理
@Super Object delegate,
// 方法的调用者对象 对原始方法的调用依靠它
@SuperCall Callable<?> callable) throws Exception {
//目标方法执行前执行日志记录
// 目标方法执行前执行日志记录
System.out.println("准备执行Method=" + method.getName());
System.out.println("方法参数: " + Arrays.toString(arguments));
System.out.println("返回类型: " + method.getReturnType().getName());
// 调用目标方法
Object result = callable.call();
//目标方法执行后执行日志记录
System.out.println("方法执行完成Method=" + method.getName());
return result;
}
}
webController:
@RestController
@RequestMapping("/test")
public class SourceWebController {
public String hello(String name) {
return null;
}
@RequestMapping("RequestMapping")
public String testRequestMapping() {
return "helloRequestMapping";
}
@GetMapping("GetMapping")
public String testGetMapping() {
return "helloGetMapping";
}
@PostMapping("PostMapping")
public void testPostMapping() {
System.out.println("helloPostMapping");
}
}
pom:
org.springframework.boot
spring-boot-starter-parent
2.1.2.RELEASE
org.springframework.boot
spring-boot-starter-web
net.bytebuddy
byte-buddy
1.17.6
net.bytebuddy
byte-buddy-agent
1.17.6
org.projectlombok
lombok