Java动态代理实现案例
动态代理是Java中非常重要的设计模式,允许在运行时动态创建代理对象,主要有两种实现方式:

JDK动态代理(基于接口)
适用场景:目标类实现了接口
// 1. 定义接口
public interface UserService {
void addUser(String name);
void deleteUser(int id);
String findUser(int id);
}
// 2. 实现类
public class UserServiceImpl implements UserService {
@Override
public void addUser(String name) {
System.out.println("添加用户:" + name);
}
@Override
public void deleteUser(int id) {
System.out.println("删除用户ID:" + id);
}
@Override
public String findUser(int id) {
System.out.println("查询用户ID:" + id);
return "用户" + id;
}
}
// 3. 实现InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogInvocationHandler implements InvocationHandler {
private Object target; // 目标对象
public LogInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("[日志] 开始执行方法:" + method.getName());
// 调用目标方法
Object result = method.invoke(target, args);
// 后置增强
System.out.println("[日志] 方法执行完成:" + method.getName());
return result;
}
}
// 4. 使用动态代理
public class JDKProxyDemo {
public static void main(String[] args) {
// 创建目标对象
UserService target = new UserServiceImpl();
// 创建代理对象
UserService proxy = (UserService) Proxy.newProxyInstance(
target.getClass().getClassLoader(), // 类加载器
target.getClass().getInterfaces(), // 接口数组
new LogInvocationHandler(target) // 调用处理器
);
// 使用代理对象
proxy.addUser("张三");
proxy.deleteUser(1);
String user = proxy.findUser(100);
System.out.println("查询结果:" + user);
}
}
CGLIB动态代理(基于继承)
适用场景:目标类没有实现接口,或需要对类进行代理
// 1. 添加依赖(Maven)
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
// 2. 目标类(无需接口)
public class UserDao {
public void addUser(String name) {
System.out.println("添加用户:" + name);
}
public final void deleteUser(int id) {
System.out.println("删除用户ID:" + id);
}
}
// 3. 实现MethodInterceptor
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxyInterceptor implements MethodInterceptor {
private Object target;
public CglibProxyInterceptor(Object target) {
this.target = target;
}
// 创建代理对象
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("[CGLIB] 前置处理");
// 调用目标方法
Object result = method.invoke(target, args);
System.out.println("[CGLIB] 后置处理");
return result;
}
}
// 4. 使用CGLIB代理
public class CglibProxyDemo {
public static void main(String[] args) {
// 创建目标对象
UserDao target = new UserDao();
// 创建代理
CglibProxyInterceptor interceptor = new CglibProxyInterceptor(target);
UserDao proxy = (UserDao) interceptor.getProxy();
// 使用代理对象
proxy.addUser("李四");
// proxy.deleteUser(2); // 注意:final方法无法被代理
}
}
通用动态代理工具类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 通用动态代理工具类
*/
public class DynamicProxyUtil {
/**
* JDK动态代理
*/
@SuppressWarnings("unchecked")
public static <T> T createJDKProxy(T target, ProxyHandler handler) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
handler.before(method, args);
Object result = method.invoke(target, args);
handler.after(method, result);
return result;
}
}
);
}
/**
* 代理处理器接口
*/
public interface ProxyHandler {
default void before(Method method, Object[] args) {}
default void after(Method method, Object result) {}
}
}
// 使用示例
public class MainDemo {
public static void main(String[] args) {
// 创建目标对象
UserService userService = new UserServiceImpl();
// 创建代理
UserService proxy = DynamicProxyUtil.createJDKProxy(userService,
new DynamicProxyUtil.ProxyHandler() {
@Override
public void before(Method method, Object[] args) {
System.out.println("通用前置处理");
}
@Override
public void after(Method method, Object result) {
System.out.println("通用后置处理");
}
}
);
// 测试
proxy.addUser("测试用户");
}
}
实际应用场景示例:事务管理
// 事务注解
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transactional {
}
// 事务代理实现
public class TransactionProxy {
@SuppressWarnings("unchecked")
public static <T> T createTransactionProxy(T target) {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
(proxy, method, args) -> {
Transactional transactional = method.getAnnotation(Transactional.class);
if (transactional != null) {
System.out.println("开启事务...");
try {
Object result = method.invoke(target, args);
System.out.println("提交事务...");
return result;
} catch (Exception e) {
System.out.println("回滚事务...");
throw e;
}
} else {
return method.invoke(target, args);
}
}
);
}
}
// 使用
public class BusinessService {
@Transactional
public void doBusiness() {
System.out.println("执行业务逻辑");
}
public void normalOperation() {
System.out.println("普通操作,无需事务");
}
}
| 特性 | JDK动态代理 | CGLIB动态代理 |
|---|---|---|
| 实现方式 | 基于接口 | 基于继承(生成子类) |
| 性能 | 较低(反射调用) | 较高(直接调用) |
| 限制 | 必须有接口 | final方法不能被代理 |
| 适用版本 | JDK 1.3+ | 需要引入cglib库 |
选择建议:
- 如果目标类有接口 → 优先使用JDK动态代理
- 如果没有接口或需要代理类本身 → 使用CGLIB
- Spring框架默认使用JDK动态代理,没有接口时自动切换CGLIB
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播