java 设计模式之代理模式

什么是代理模式?

代理模式(Proxy Pattern)是一种经典的设计模式,它提供了一个代理对象来控制对另一个对象的访问。

代理模式主要解决的是对象直接的业务关系,即将行为请求和行为实现分离出来,以达到增强类的功能的目的。

Java代理模式的分类

Java代理模式可以分为三类:静态代理、动态代理和CGLIB代理。

静态代理

静态代理是指在程序运行前已经确定需要代理的类或接口,因此在Java的编译期间可以动态地生成代理类。

下面是一个静态代理的示例:

// 接口
public interface ISubject {
    void doSomething();
}

// 实现类
public class RealSubject implements ISubject {
    @Override
    public void doSomething() {
        System.out.println("Real subject do something.");
    }
}

// 代理类
public class StaticProxy implements ISubject {
    private ISubject realSubject;

    public StaticProxy(ISubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void doSomething() {
        System.out.println("Before real subject do something.");
        realSubject.doSomething();
        System.out.println("After real subject do something.");
    }
}

在上面的示例中,ISubject是一个接口,定义了需要被代理的类的行为。

RealSubject是实现了ISubject接口的具体类,StaticProxyISubject接口的代理类,它通过构造函数接收一个ISubject类型的对象,并在代理中透明地调用了该对象。

代理类在方法调用前后执行了一些逻辑,可以用来添加额外的功能,如日志记录、安全检查等。

动态代理

动态代理是指在程序运行时,通过反射机制对需要代理的类或接口进行代理,因此不需要事先知道需要代理的类或接口,也不需要声明与它匹配的代理类。

动态代理在Java中主要通过java.lang.reflect.Proxy类实现。

下面是一个动态代理的示例:

// 接口
public interface ISubject {
    void doSomething();
}

// 实现类
public class RealSubject implements ISubject {
    @Override
    public void doSomething() {
        System.out.println("Real subject do something.");
    }
}

// InvocationHandler实现类
public class DynamicProxy implements InvocationHandler {
    private Object realObject;

    public DynamicProxy(Object realObject) {
        this.realObject = realObject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before real subject do something.");
        Object result = method.invoke(realObject, args);
        System.out.println("After real subject do something.");
        return result;
    }
}

同上,ISubject是一个接口,定义了需要被代理的类的行为。

RealSubject是实现了ISubject接口的具体类。

DynamicProxy是动态代理类的实现类,它实现了InvocationHandler接口,并在代理中透明地调用了被代理对象。代理类可以在方法调用前后执行一些逻辑。

由于动态代理在运行时通过反射机制生成代理对象,因此需要保证被代理的类或接口具有一些特定的条件:必须是一个接口或者是继承了至少一个接口的类,同时这些接口必须是public访问权限的。

CGLIB代理

CGLIB代理是指使用CGLIB库动态生成子类代理的过程,它可以直接对类进行代理,因此被代理的类无需实现任何接口。

下面是一个使用CGLIB代理的示例:

// 实现类
public class RealSubject {
    public void doSomething() {
        System.out.println("Real subject do something.");
    }
}

// MethodInterceptor实现类
public class CGLIBProxy implements MethodInterceptor {
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before real subject do something.");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After real subject do something.");
        return result;
    }
}

// 测试类
public class TestCGLIBProxy {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealSubject.class);
        enhancer.setCallback(new CGLIBProxy());
        RealSubject proxy = (RealSubject) enhancer.create();
        proxy.doSomething();
    }
}

在上面的示例中,RealSubject是一个具体的实现类,没有实现任何接口。

CGLIBProxy是基于CGLIB库实现的代理类,它实现了MethodInterceptor接口,并在代理中透明地调用了被代理对象。CGLIB代理需要使用Enhancer类来创建代理对象。

Java代理模式的应用场景

Java代理模式比较适合在以下情况下使用:

  • 远程代理:将网络中的一个对象作为本地对象使用,通过网络的方式实现远程方法调用。
  • 虚拟代理:缓存对象的创建和销毁等开销较大的操作,将这些操作延迟到真正需要的时候再执行。
  • 安全代理:控制对象的访问权限,保证只有授权的用户才能使用对象。
  • 智能代理:在访问对象的时候,加入一些额外的逻辑,如调用对象前后执行一些操作、记录日志等。
  • 延迟加载:当需要的时候再去创建对象,从而优化系统性能或者节约资源。

结论

Java代理模式是一种经典的设计模式,可以帮助我们将行为请求和行为实现分离出来,以达到增强类的功能的目的。根据Java代理模式的不同实现方式,我们可以将代理分为静态代理、动态代理和CGLIB代理三种不同的类型。在实际开发中,我们可以根据具体业务场景的不同来选择使用不同的代理类型。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值