Java Agent、JDK动态代理、CGLIB 的区别

在介绍 Apptalking Java Agent 的技术的时候,很多研发童靴会问道,Agent 也是通过拦截方法进行方法监控的 ,和JDK动态代理技术、CGLIB技术有什么区别? 以下就监控实现上简单介绍一下三者的区别。

监控示例

用以上的3中技术监控 UserServiceImpl 业务类。
其代码如下:

1
2
3
4
5
6
7
8
9
10

public interface IUserService{
public addUser(User user);
}

public class UserServiceImpl implements IUserService {
public addUser(User user){
System.out.println("添加用户!")
}
}

JDK动态代理伪代码实现

JDK动态代理是基于接口的,JDK 会动态生成实现类的字节码,加载字节码生成相应的类。
使用起来相当于以下的代码:

1
2
3
4
5
6
public UserServiceProxy implements IUserService{
IUserService userService = new UserServiceImpl();
public addUser(User user){
userService.add(user);
}
}

CGLIB代理伪代码实现

CGLI 是基于继承实现代理机制的,所以其不需要接口,CGLIB 底层使用的 ASM 生成一个代理目标类的子类,来实现代理功能,使用起来相当于以下的代码:

1
2
3
4
5
6
7
public UserServiceProxy extends UserServiceImpl{
UserServiceImpl userService = new UserServiceImpl();
// 重写父类的方法
public addUser(User user){
userService.add(user);
}
}

Java Agent 伪代码实现

Java Agent 是通过字节码修改实现的,但是Java Agent 没有创建新的Class 而是直接修改了原始Class,其原理如下:

1
2
3
4
5
6
7
public class UserServiceImpl implements IUserService {
public addUser(User user){
// 嵌入监控代码 onMethodBegin()
System.out.println("添加用户!")
// 嵌入监控代码 onMethodEnd()
}
}