9-静态代理&动态代理


学习AOP之前,你必须要了解动态代理。

静态代理

代理
角色分析:

  • 抽象角色:一般会使用接口或者抽象类
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
  • 客户:访问代理对象的人

代码分析

  • 抽象角色
public interface Rent {
    void rent();
}
  • 真实角色
public class Landlord implements Rent {
    @Override
    public void rent() {
        System.out.println("出租房子");
    }
}
  • 代理角色
public class ProxyRent implements Rent {
    //被代理的类
    private Landlord landlord; //传入被代理的类
    public ProxyRent(Landlord landlord){
        this.landlord = landlord;
    }
    
    @Override
    public void rent() {
        SeeHouse();
        landlord.rent();
        contract();
        agencyFee();
    }

    public void SeeHouse(){
        System.out.println("房屋中介看您看房");
    }

    public void contract(){
        System.out.println("房屋中介安排您们签合同");
    }

    public void agencyFee(){
        System.out.println("房屋中介收取中介费");
    }
}
  • 客户
public class Test {

    public static void main(String[] args) {
        ProxyRent proxyRent = new ProxyRent(new Landlord());
        proxyRent.rent();
    }
}
  • 结果
    在这里插入图片描述

如果您还是不明白,那我再举一个栗子。

  • 抽象角色:Service 接口
public interface Service {
    void add();
    void sub();
    void mul();
    void div();
}
  • 真实角色:被代理的角色(实现了Service 接口)
public class ServiceImpl implements Service {
    @Override
    public void add() {
        System.out.println("加法");
    }

    @Override
    public void sub() {
        System.out.println("减法");
    }

    @Override
    public void mul() {
        System.out.println("乘法");
    }

    @Override
    public void div() {
        System.out.println("除法");
    }
}
  • 代理角色:(实现了Service 接口并传入ServiceImpl 对象,且有额外操作log() )
public class Log implements Service{

    private ServiceImpl serviceImpl;
    public Log(ServiceImpl serviceImpl){
        this.serviceImpl = serviceImpl;
    }

    @Override
    public void add() {
        log();
        serviceImpl.add();
    }

    @Override
    public void sub() {
        log();
        serviceImpl.sub();
    }

    @Override
    public void mul() {
        log();
        serviceImpl.mul();
    }

    @Override
    public void div() {
        log();
        serviceImpl.div();
    }

    public void log(){
        System.out.println("我是添加的日志");
    }
}
  • 客户:访问代理对象的人
public class Test {
    public static void main(String[] args) {
        Log log = new Log(new ServiceImpl());
        log.add();
        log.sub();
        log.mul();
        log.div();
    }
}

静态代理,到此结束。

动态代理(Proxy与InvocationHandler)

  • 抽象角色:一般会使用接口或者抽象类
public interface Rent {
    void rent();
}
  • 真实角色:被代理的角色
public class Landlord implements Rent {
    @Override
    public void rent() {
        System.out.println("出租房子");
    }
}
  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
//通过这个类,获取代理类
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的接口
    private Rent rent;

    public void setRent(Rent rent){
        this.rent = rent;
    }

   /*
   返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
        loader:定义代理类的类加载器
        interfaces:代理类要实现的接口列表
        h:指定调用处理程序(InvocationHandler)
   */
    public Rent getProxyInstance(){
        return (Rent)Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(), this);
    }

    @Override
    //处理代理实例上的方法调用并返回结果。
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        Object result = method.invoke(rent, args); // 反射
        return result;
    }

    public void seeHouse(){
        System.out.println("房屋中介带你看房");
    }
}
  • 客户:访问代理对象的人
public class Test {
    public static void main(String[] args) {

        //真实对象
        Landlord landlord = new Landlord();

        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setObject(landlord);

        //获取代理对象
        Rent instance = (Rent)pih.getProxyInstance();
        instance.rent();

    }
}

如果你看不懂,没关系,我给你提供了获取万能代理类

//通过这个类,获取代理类
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的接口
    private Object target;

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

   /*
   返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
        loader:定义代理类的类加载器
        interfaces:代理类要实现的接口列表
        h:指定调用处理程序(InvocationHandler)
   */
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(), this);
    }

    @Override
    //处理代理实例上的方法调用并返回结果。
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        Object result = method.invoke(target, args); // 反射
        return result;
    }

    public void seeHouse(){
        System.out.println("房屋中介带你看房");
    }
}

下一篇:AOP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值