代理模式,看完就能懂

代理模式有静态代理和动态代理:

动态代理的实现有多种:

  • 基于接口—JDK动态代理
  • 基于类–Cglib动态代理
  • java字节码实现:javasist(有待学习)

静态代理:

静态代理首先需要的也是接口,需要代理类去实现被代理类所实现的接口,如图:在这里插入图片描述

//出租接口
public interface Rent {

    public void rentHouse();
}
//房东类
public class Landlord implements Rent{

    @Override
    public void rentHouse() {
        System.out.println("出租房子+房子信息");
    }
}
//代理类(先理解为中介)
public class StaticProxy implements Rent{

    private Landlord landlord;

    public void setLandlord(Landlord landlord) {
        this.landlord = landlord;
    }

    @Override
    public void rentHouse() {
        //代理可以做其他事
        System.out.println("陪你看房");
        //代理执行方法
        landlord.rentHouse();
        System.out.println("售后服务");
    }
}
public class Test {
    public static void main(String[] args) {
    	//租房子得有一个房东
        Landlord landlord = new Landlord();
        //再来个中介
        StaticProxy agent = new StaticProxy();
        //理解为将房东信息给中介
        agent.setLandlord(landlord);
        //找不到房东,通过中介租房子
        agent.rentHouse();
    }
}

理解完静态代理,再看看代码,发现如果每次需要代理一个类,就需要重新写一个代理类,这样的话会大大增加代码量,于是基于静态代理,动态代理又来了。

动态代理:

分析静态代理上面的代码,可以看出,只要我们在代理类中的’房东’(Landlord)不写死,再稍作修改,我们就可以用一个类去代理多个。而JDK给我们提供了InvocationHandler接口和Proxy类,我们就可以实现动态代理。

//还是一个必要的接口
public interface UserDao {
    public void add();
    public void delete();
}
//我们的被代理类
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("执行add");
    }

    @Override
    public void delete() {
        System.out.println("执行delete");
    }
}
//我们的代理类,首先必须实现InvocationHandler接口//核心
public class UserDaoProxy implements InvocationHandler {

    private Object o;
	//通过set方式动态设置这个被代理对象
    public void setO(Object o) {
        this.o = o;
    }
    
	//通过proxy的newProxyInstance获取被代理之后的对象(实际还是反射实现)//核心
    public Object getObject(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),o.getClass().getInterfaces(),this);
    }

	//必须重写invoke//核心
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log();
        //通过反射去调用想要调用的方法
        return method.invoke(o, args);
    }

	//增加的业务
    public void log(){
        System.out.println("[Debug] 增加了日志方法");
    }
}
//测试方法
 public static void main(String[] args) {
 		//不论怎么我们还是要一个被代理类
        UserDaoImpl userDaoImpl = new UserDaoImpl();
        UserDaoProxy userDaoProxy = new UserDaoProxy();
        //把被代理类给到代理类
        userDaoProxy.setO(userDaoImpl);
        //这个userDao是已经被代理的对象
        UserDao userDao = (UserDao)userDaoProxy.getObject();
        userDao.add();

    }

这样测试下来,发现我们可以在不改变原来代码的基础上,加入新的业务。这就是JDK原生的动态代理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值