JAVA 设计模式 代理

代理设计模式是一种结构型设计模式,它允许通过代理对象控制对另一个对象(即目标对象)的访问。这种模式在不改变目标对象代码的前提下,为其提供额外的功能或控制。

代理模式的核心组件

  • 接口(Subject):定义目标对象和代理对象的共同行为。
  • 目标对象(RealSubject):实现接口的具体对象,是代理对象所代表的真实对象。
  • 代理对象(Proxy):持有目标对象的引用,并实现与目标对象相同的接口,在调用目标对象的方法前后可以添加额外逻辑。

静态代理

静态代理需要手动编写代理类,在编译时就已经确定了代理关系。以下是一个静态代理的示例:
// 接口定义
interface UserService {
    void addUser(String username);
}

// 目标对象实现类
class UserServiceImpl implements UserService {
    @Override
    public void addUser(String username) {
        System.out.println("添加用户:" + username);
    }
}

// 静态代理类
class UserServiceProxy implements UserService {
    private UserService target;

    public UserServiceProxy(UserService target) {
        this.target = target;
    }

    @Override
    public void addUser(String username) {
        System.out.println("Before method execution");
        target.addUser(username);
        System.out.println("After method execution");
    }
}

// 测试类
public class StaticProxyExample {
    public static void main(String[] args) {
        UserService target = new UserServiceImpl();
        UserService proxy = new UserServiceProxy(target);
        proxy.addUser("John");
    }
}

}

动态代理(Java 反射机制)

Java支持动态代理,允许在运行时创建代理类。以下是一个简单示例:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 主题接口
interface Animal {
    void sound();
}

// 真实主题类
class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("Woof!");
    }
}

// 动态代理处理器
class AnimalInvocationHandler implements InvocationHandler {
    private final Object target;

    public AnimalInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method call: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After method call: " + method.getName());
        return result;
    }
}

// 客户端代码
public class DynamicProxyDemo {
    public static void main(String[] args) {
        // 创建真实对象
        Animal dog = new Dog();

        // 创建代理处理器
        InvocationHandler handler = new AnimalInvocationHandler(dog);

        // 创建动态代理对象
        Animal proxyDog = (Animal) Proxy.newProxyInstance(
            Animal.class.getClassLoader(),
            new Class[]{Animal.class},
            handler
        );

        // 调用代理方法
        proxyDog.sound();
    }
}

应用场景

AOP(面向切面编程):

        在方法前后添加横切关注点(如日志、权限验证)。

远程代理:

        隐藏网络通信细节,使远程调用如同本地调用。

延迟加载:

        在真正需要对象时才初始化(如 Hibernate 的懒加载)。

缓存代理:

        优先返回缓存结果,减少重复计算。

总结

Java 动态代理通过Proxy类和InvocationHandler接口实现了运行时的方法拦截和增强。其核心优势在于非侵入性灵活性,能够在不修改原有代码的前提下,为对象添加额外功能,是实现 AOP、RPC 等复杂功能的基础技术。

你可能感兴趣的:(JavaEE,设计模式,java,设计模式,代理模式)