Spring AOP前奏之代理模式

120 阅读3分钟

静态代理

角色分析:

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

代理模式的好处:

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共也就就交给代理角色!实现了业务的分工!
  • 公共业务发生扩展的时候,方便集中管理!

缺点:

  • 一个真实角色就会产生一个代理角色;代码量会翻倍开发效率会变低

代码步骤:

  • 接口
  • 真实角色
  • 代理角色
  • 客户端访问代理角色

样例

接口

public interface Rent {
    void rent();
}

真实角色

public class Host implements Rent{//真实角色实现接口
    @Override
    public void rent() {
        System.out.println("房东要出租房屋。。。");
    }
}

代理角色

public class Proxy implements Rent{
    private Host host;

    public Proxy(Host host) {
        this.host = host;
    }

    public Proxy() {
    }

    @Override
    public void rent() {//代理Host
        host.rent();
    }
    public void extend01(){
        System.out.println("在代理真实角色的基础上扩展业务.。。01");
    }
    public void extend02(){
        System.out.println("在代理真实角色的基础上扩展业务。。。02");
    }
    public void extend03(){
        System.out.println("在代理真实角色的基础上扩展业务。。。03");
    }
}

客户端访问代理角色

public class Client {
    public static void main(String[] args) {
        Proxy proxy=new Proxy(new Host());
        proxy.rent();//通过代理使用Host的方法
        proxy.extend01();
        proxy.extend02();
        proxy.extend03();
    }
}

动态代理

根据如上的介绍,你会发现每个代理类只能为一个接口服务,这样程序开发中必然会产生许多的代理类 所以我们就会想办法可以通过一个代理类完成全部的代理功能,那么我们就需要用动态代理

在上面的示例中,一个代理只能代理一种类型,而且是在编译器就已经确定被代理的对象。而动态代理是在运行时,通过反射机制实现动态代理,并且能够代理各种类型的对象

在Java中要想实现动态代理机制,需要java.lang.reflect.InvocationHandler接口和 java.lang.reflect.Proxy 类的支持

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的!
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
  • 基于接口---JDK动态代理【我们在这里使用】
  • 基于类: cglib
  • java字节码实现: javasist

JDK动态代理

  • 动态代理的表现形式即同一个代理对象可以代理多个被代理对象,不再像之前的静态代理仅约束于一个被代理对象。

  • 在java中,基于JDK的代理类和被代理类,必须实现同一个接口。

样例

  • 接口
public interface Business {
    void doBusiness();
}
  • 真实对象(多个类实现同一个接口)
public class Boss01 implements Business{
    public void doBusiness() {
        System.out.println("老板1号在谈生意");
    }
    public void aVoid(){
        System.out.println("dfgdgssdfg");
    }
}
public class Boss02 implements Business{
    public void doBusiness() {
        System.out.println("老板2号在谈生意");
    }
}
public class Boss03 implements Business{
    @Override
    public void doBusiness() {
        System.out.println("老板3号在谈生意");
    }
}

  • 实现InvocationHandler接口
public class ProxyIH implements InvocationHandler {//
    private Object target;//真实对象(被代理的对象)

    public void setTarget(Object target) {//设置真实对象
        this.target = target;
    }
    public Object getTarget(){//获取具体被代理的真实对象
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {//该方法可以实现业务扩展,以及执行被代理对象的方法
        extend();
        Object result = method.invoke(target,args);
        log(target.getClass().getName());
        return result;
    }
    public void extend(){
        System.out.println("代理扩展业务:展示老板动态");
    }
    public void log(String msg){
        System.out.println("代理了"+msg+"的业务");
    }
}
  • test(Client)

动态代理,代理的是接口

public class Client {
    public static void main(String[] args) {
        ProxyIH proxyIH = new ProxyIH();
        proxyIH.setTarget(new Boss01());
//        proxyIH.setTarget(new Boss02());
//        proxyIH.setTarget(new Boss03());
        Business business = (Business) proxyIH.getTarget();//动态代理,代理的是接口
        business.doBusiness();
    }
}

image.png