代理模式

本文介绍了Java中的两种代理模式:静态代理和动态代理。在静态代理中,通过创建代理类来实现对目标类的功能增强,如添加日志功能。动态代理则利用`java.lang.reflect`包中的`InvocationHandler`接口和`Proxy`类,在运行时动态生成代理对象,调用目标对象的方法。动态代理更灵活,不需要预先创建具体的代理类。
摘要由CSDN通过智能技术生成

1.静态代理:

在这里插入图片描述
需求:要在实现类中添加功能,可是很多时候我们不能更改源码,这时候使用代理完成。
如:需要增添日志信息。

  1. 接口:
public interface Service {
    public void add();
    public void delete();
    public void upadate();
    public void query();
}
  1. 实现类:
public class ServiceImpl implements Service {
    public void add() {
        System.out.println("add");
    }

    public void delete() {
        System.out.println("delete");
    }

    public void upadate() {
        System.out.println("update");
    }

    public void query() {
        System.out.println("query");
    }
}
  1. 代理:
public class ServiceProxy implements Service{
    private ServiceImpl service;

    public ServiceProxy() {
    }

    public ServiceProxy(ServiceImpl service) {
        this.service = service;
    }

    public void add() {
        Log("add");
        service.add();
    }

    public void delete() {
        Log("delete");
        service.delete();
    }

    public void upadate() {
        Log("update");
        service.upadate();
    }

    public void query() {
        Log("query");
        service.query();
    }

    public void Log(String name){
        System.out.println("[DeBug]:正在执行:"+name);
    }
}
  1. 测试:
    @Test
    public void test(){
        ServiceImpl service = new ServiceImpl();
        ServiceProxy serviceProxy = new ServiceProxy(service);
        serviceProxy.upadate();

    }

1.1 特点:

代理类需要实现接口,本质上是在实现接口方法内调用实现类的方法

2.动态代理

使用了java.lang.reflect包下的InvocationHandler接口和proxy类的newProxyInstance()方法 。
本质上会在内存中动态的构建代理对象,通过代理对象调用目标对象方法。

Object invoke(Object proxy, 方法 method, Object[] args)throws Throwable
处理代理实例上的方法调用并返回结果。 当在与之关联的代理实例上调用方法时,将在调用处理程序中调用此方法。
参数
proxy - 调用该方法的代理实例
method -所述方法对应于调用代理实例上的接口方法的实例。 方法对象的声明类将是该方法声明的接口,它可以是代理类继承该方法的代理接口的超级接口。
args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。 原始类型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。

proxy类的静态方法:
public static Object newProxyInstance(ClassLoader loader , 类<?>[] interfaces , InvocationHandler h) throws IllegalArgumentException
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序
loader :类加载器来定义代理类
interfaces : 代理类实现的接口列表
h : 动态代理方法在执行时,会调用h里面的invoke方法去执行

动态代理类

public class dynamicProxy {
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    public Object getProxy(){
        Object o = Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Log(method.getName());
                        method.invoke(target, args);
                        return null;
                    }
                }
        );
        return o;
    }

    public void Log(String inf){
        System.out.println("[DeBug]:"+inf+"已经执行");
    }
}
public class Mytest {
    public static void main(String[] args) {
        ServiceImpl service = new ServiceImpl();
        dynamicProxy dynamicProxy = new dynamicProxy();
        dynamicProxy.setTarget(service);
        Service proxy = (Service) dynamicProxy.getProxy();
        proxy.add();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值