代理模式,静态代理、动态代理详解实例(简单明了)

代理模式

优点:
1、可以让功能共纯粹,实现业务的分工单一性。
2、业务扩展时通过代理可以不影响现有代码。

示例1、 静态代理:客户租房(消费者)>>>通过中介(代理)>>>房东(生产者)
房东与中介有共同的出租房的方法,可以抽象出共同的接口

//出租房的接口,里面有出租的抽象接口
public interface Rent {
     // 出租房
    void rent();
}
//房东有一个房子,实现出租房接口
public class Host implements Rent{
    //房子有一个出租的方法
    public void rent(){
        System.out.println("出租房子");
    }
}
/**
 * 中介(代理),中介不仅有出租房的方法,还有其他方法,比如:带顾客看房、签订合同、收取中介费
 * 中介实际出租的是房东的房子,所以中介要调用房东的出租房方法,客户要租那个房子是由客户决定的,创建代理时传要过来房子对象
 */
public class Proxy implements Rent{

    //房东(房子)
    private Host host;

    //构造方法传入房子对象
    public Proxy(Host host) {
        this.host = host;
    }

    //代理租房方法,代理方法中可以操作代理这的特有方法
    //中介可以带客户看房,确定后签订合同,
    @Override
    public void rent() {
        seeHome();//看房
        host.rent();//调用房东的租房方法
        hetong();//签合同
    }

    /**
     * 中介特有方法-看房
     */
    public void seeHome(){
        System.out.println("带你看房");
    }
    /**
     * 中介特有方法-签合同
     */
    public void hetong(){
        System.out.println("签承租合同");
    }
}
public class Client {
    public static void main(String[] args) {
        //创建房子对象
        Host host = new Host();
        //创建代理对象,并将房子信息传入
        Rent rent=new Proxy(host);
        rent.rent();
    }
}

示例2、 动态代理:增删改查用户>>>动态代理>>>用户管理
增删改查用户时,调用方法前后增加日志信息,不修改原有代码

//用户管理接口
public interface UserService {
    void add();
    void delete();
    void update();
    void query();
}
/**
 * 用户管理实现类
 */
public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("添加用户");
    }

    @Override
    public void delete() {
        System.out.println("删除用户");
    }

    @Override
    public void update() {
        System.out.println("更新用户");
    }

    @Override
    public void query() {
        System.out.println("查询用户");
    }
}

//引用reflect反射包下的类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 万能动态代理类,通过反射机制调用被代理的方法
 */
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的目标对象,用万能对象声明
    private Object target;

    //可以用set方法也可以用构造方法赋值
    public void setTarget(Object target) {
        this.target = target;
    }

    //通过反射动态获取代理对象
    public Object getProxy() {
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    //通过反射调用要执行的方法,在该方法中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理,调用方法前执行");
        beforeLog();
        Object invoke = method.invoke(target, args);
        afterLog()
        System.out.println("动态代理,调用方法后执行");
        return invoke;
    }

    private void beforeLog() {
        System.out.println("方法前输出日志");
    }

    private void afterLog() {
        System.out.println("方法后输出日志");
    }
}
/**
 * 消费者
 */
public class Client {
    public static void main(String[] args) {
        //创建用户Service对象
        UserService userService1 = new UserServiceImpl();

        //直接调用方法
        userService1.add();
        userService1.delete();

        //通过代理调用方法
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setTarget(userService1);
        UserService userService2 = (UserService) pih.getProxy();
        System.out.println("--------");
        userService2.add();
        System.out.println("--------");
        userService2.delete();
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乾坤鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值