在 Java 中,**Proxy(代理)**通常分为两类:
下面从「原理」角度系统说明。
代理模式:为某个对象提供一个代理对象,由代理对象控制对真实对象的访问。
核心目的:
在编译期就手动编写代理类,代理类实现和目标类相同的接口,并持有目标对象引用。
interface UserService {
void save();
}
class UserServiceImpl implements UserService {
public void save() {
System.out.println("保存用户");
}
}
class UserServiceProxy implements UserService {
private UserService target;
public UserServiceProxy(UserService target) {
this.target = target;
}
public void save() {
System.out.println("前置增强");
target.save();
System.out.println("后置增强");
}
}
java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler运行期动态生成代理类(字节码)
步骤:
InvocationHandlerProxy.newProxyInstance() 创建代理对象InvocationHandler.invoke()UserService proxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class[]{UserService.class},
(obj, method, args) -> {
System.out.println("前置");
Object result = method.invoke(target, args);
System.out.println("后置");
return result;
}
);
ProxyInvocationHandlersun.misc.ProxyGenerator 生成字节码✅ 只能代理 接口 ❌ 不能代理类(无接口的类不行)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
System.out.println("前置");
Object result = proxy.invokeSuper(obj, args);
System.out.println("后置");
return result;
});
UserService proxy = (UserService) enhancer.create();
✅ 可代理类
✅ 不需要接口
❌ 不能代理 final 类 / final 方法
| 对比项 | JDK 动态代理 | CGLIB |
|---|---|---|
| 实现方式 | 接口 | 继承 |
| 性能 | 调用稍慢 | 生成慢,调用快 |
| 限制 | 必须有接口 | 不能 final |
| 使用场景 | Spring 接口 Bean | Spring 类 Bean |
@EnableAspectJAutoProxy(proxyTargetClass = true) 强制 CGLIBJava Proxy 的本质是:在运行期生成代理类,将方法调用拦截并转发到统一的处理逻辑,从而实现功能增强。
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。