Java代理静态/动态代理模式

Java代理模式是一种结构型设计模式,通过代理对象控制对目标对象的访问,主要分为静态代理和动态代理两种实现方式。

一、静态代理
// 1. 定义服务接口
interface DatabaseService {
    void executeQuery(String sql);
}

// 2. 真实服务类
class RealDatabaseService implements DatabaseService {
    @Override
    public void executeQuery(String sql) {
        System.out.println("执行数据库查询: " + sql);
    }
}

// 3. 代理类
class DatabaseServiceProxy implements DatabaseService {
    private RealDatabaseService realService;
    
    public DatabaseServiceProxy() {
        this.realService = new RealDatabaseService();
    }
    
    @Override
    public void executeQuery(String sql) {
        System.out.println("【代理】开始事务");
        realService.executeQuery(sql); // 委托给真实对象
        System.out.println("【代理】提交事务");
    }
}

// 4. 客户端使用
public class Main {
    public static void main(String[] args) {
        DatabaseService proxy = new DatabaseServiceProxy();
        proxy.executeQuery("SELECT * FROM users");
    }
}
 

  1. 特点:代理类在编译期确定,需手动为每个目标类编写代理类3
  2. 实现步骤:
    • 定义接口
    • 创建目标类实现接口
    • 创建代理类实现相同接口并持有目标对象引用10
  3. 缺点:需为每个目标类创建代理类,代码冗余6

二、动态代理

  1. JDK动态代理:

    • 基于接口实现,通过Proxy类和InvocationHandler接口在运行时生成代理类5
    • 核心方法:Proxy.newProxyInstance()
    • 示例流程:
      // 定义接口和实现类
      interface Service { void execute(); }
      class RealService implements Service {...}
      
      // 创建InvocationHandler
      class MyHandler implements InvocationHandler {
          private Object target;
          public Object invoke(Object proxy, Method method, Object[] args) {...}
      }
      
      // 生成代理对象
      Service proxy = (Service)Proxy.newProxyInstance(...);
      
      
  2. CGLIB动态代理:


    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    import java.lang.reflect.Method;

    // 1. 目标类(非final类)
    class UserService {
        public void addUser(String name) {
            System.out.println("添加用户: " + name);
        }
        
        public String getUserInfo(int id) {
            return "用户ID:" + id;
        }
    }

    // 2. 方法拦截器
    class CglibProxy implements MethodInterceptor {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, 
                              MethodProxy proxy) throws Throwable {
            System.out.println("【CGLIB代理】前置处理");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("【CGLIB代理】后置处理");
            return result;
        }
    }

    // 3. 测试类
    public class CglibDemo {
        public static void main(String[] args) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(UserService.class);
            enhancer.setCallback(new CglibProxy());
            
            UserService proxy = (UserService) enhancer.create();
            proxy.addUser("张三");
            System.out.println(proxy.getUserInfo(1001));
        }
    }
     

    • 基于继承实现,可代理无接口的类
    • 通过MethodInterceptor接口实现方法拦截

三、核心区别

特性 JDK动态代理 CGLIB动态代理
实现基础 接口 继承
性能 调用快,创建慢 创建快,调用稍慢
限制 必须实现接口 不能代理final类/方法

典型应用场景包括:AOP编程、远程调用、访问控制、日志记录等。动态代理通过运行时字节码生成技术,解决了静态代理的代码冗余问题。

你可能感兴趣的:(代理模式,java,开发语言)