代理模式(Proxy)总结

代理模式介绍

所谓代理模式,就是为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象,这样做的好处:可以在目标对象实现的基础上,增强额外的功能操作,即拓展目标对象的功能。

代理模式的形式

主要有三种形式:

  1. 静态代理
  2. 动态代理(JDK代理、接口代理)
  3. Cglib代理(可在内存中动态的创建对象,而不需要实现接口,也属于动态代理的范畴)

静态代理

基本介绍

静态代理在使用时,需要定义接口或者父类,被代理对象(即目标对象)与代理对象一起实现相同的接口或者继承相同的父类。见下图。
在这里插入图片描述

代码实现

接口IntDao.java

public interface IntDao {
    void show();
}

目标对象(被代理对象)ImplDao.java

public class ImplDao implements IntDao{
    @Override
    public void show() {
        System.out.println("目标对象的show方法");
    }
}

代理对象ImplDaoProxy.java

public class ImplDaoProxy implements IntDao {
    private IntDao target;

    public ImplDaoProxy(IntDao target) {
        this.target = target;
    }

    @Override
    public void show() {
        System.out.println("开始代理");
        //完成某些操作
        target.show();
        System.out.println("代理结束");
    }
}

main方法Test.java

public class Test {

    public static void main(String[] args)  {
        //创建被代理对象
        ImplDao implDao = new ImplDao();
        //创建代理对象
        ImplDaoProxy implDaoProxy = new ImplDaoProxy(implDao);
        //通过代理对象,调用被代理对象的方法
        implDaoProxy.show();
    }
}

静态代理优缺点分析:

  1. 优点:不需要修改目标对象,通过代理对象对目标对象功能增强。
  2. 缺点:因为代理对象与被代理对象实现同样的接口,因此需要有很多代理类;
  3. 缺点:一旦接口增加新的方法,代理类与目标类都要进行修改。

在这里插入图片描述

动态代理

基本介绍

  1. 代理对象不需要实现接口,目标对象仍然需要实现接口。
  2. 代理对象通过JDK的API动态的在内存中构建代理对象。
  3. 动态代理也叫做:JDK代理、接口代理。

API:

  1. 所在包java.lang.reflect.Proxy
  2. 核心方法public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

介绍
Proxy.newProxyInstance():产生代理接口的实例。仅能代理实现至少一个接口的类。

ClassLoader:类加载器。即被代理的接口的类加载器。
Class[] interface:被代理对象的父接口
InvocationHandler:将要在代理中实现的功能写在该对象中
InvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行

Object proxy:代理对象自身的引用。
Method method:当前被调用的方法。
Object[] args:当前被调用方法用到的参数

在这里插入图片描述

代码实现

接口IntDao.java

public interface IntDao {
    void show();
}

目标对象(被代理对象)ImplDao .javas

public class ImplDao implements IntDao{
    @Override
    public void show() {
        System.out.println("目标对象的show方法");
    }
}

代理对象生成工厂ProxyFactory.java

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

public class ProxyFactory {
    private Object target;

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

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开始代理");
                        //System.out.println(method.getName()); //输出调用的方法名
                        Object returnVal = method.invoke(target, args);
                        System.out.println("代理结束");
                        return returnVal;
                    }
                });
    }

}

测试类Test.java

public class Test {
    public static void main(String[] args) {
        //目标对象
        IntDao target = new ImplDao();
        //创建代理对象
        ProxyFactory proxyFactory = new ProxyFactory(target);
        IntDao proxyInstance = (IntDao)proxyFactory.getProxyInstance();
        //调用目标对象的方法
        proxyInstance.show();
    }
}

总结

动态代理需要实现接口才可以使用。因为使用反射实现,速度不是很快。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值