代理模式

2021-05-06  本文已影响0人  金煜博

什么是代理模式?

一个对象被另一个对象进行代理,代理对象可以引用被代理对象,并且可以在被代理对象之前之后进行相关的操作,现实中俗称中介。

静态代理

每一个代理对象都需要手动完成创建

1.使用接口方式实现

通过引用被代理类调用代理类的方法

示例图
图片.png
示例代码

1.创建抽象的行为接口

public interface Behavior { 
    void renting();
}

2.创建被代理类-房主

public class Homeowners implements Behavior {
    @Override
    public void renting() {
        System.out.println("客户要租房");
    }
}

3.创建代理类-中介

public class AgencyProxy implements Behavior  {
    private Homeowners renting;

    public AgencyProxy(Homeowners renting) {
        this.renting = renting;
    }

    @Override
    public void renting() {
        System.out.println("租房前看房源");
        renting.renting();
        System.out.println("租房后签合同");
    }
}

4.创建客户类-启动类

public class Customer {
    public static void main(String[] args) {
        AgencyProxy agencyProxy = new AgencyProxy(new Homeowners());
        agencyProxy.renting();
    }
}

2.使用继承方式实现

修改代理类让代理类继承被代理类(t通过super关键字调用被代理方法)

public class AgencyProxy  extends  Homeowners {
    private Homeowners renting;

    @Override
    public void renting() {
        System.out.println("租房前看房源");
        super.renting();
        System.out.println("租房后签合同");
    }
}

修改客户类- 启动类

public class Customer {
    public static void main(String[] args) {
        AgencyProxy agencyProxy = new AgencyProxy();
        agencyProxy.renting();
    }
}

运行结果


图片.png

动态代理

通过java反射或字节码技术在运行时自动创建代理对象

jdk动态代理

实现InvocationHandler接口生成jdk动态代理类

示例代码

创建JdkInvocationHandler类

public class JdkInvocationHandler implements InvocationHandler {
    //目标代理对象
    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("租房前看房源");
        Object result = method.invoke(target, args);//通过java反射机制获取目标代理对象的方法
        System.out.println("租房后签合同");
        return result;
    }

    //使用jdk动态代理创建代理类
    public <T> T getProxy(){
     //1.目标对象 2.目标对象实现的接口 3.当前类
        Object o =  Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        return (T) o;
    }
}

修改客户类- 启动类

public class Customer {
    public static void main(String[] args) {
        //获取代理类
        Behavior proxy = new JdkInvocationHandler(new Homeowners()).getProxy();
        proxy.renting();
    }
}

cglib动态代理

Cglib是代码生成类库。可以在运行时扩展java类与实现java接口,底层使用asm字节码可动态生成新的类。使用cglib动态代理可以生成被代理类的子类,子类重写父类非final修饰的方法,在子类的方法中对父类方法进行拦截。

示例代码

1.引入cglib包

   <dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.12</version>
        </dependency>
    </dependencies>

2.创建Cglib类

public class Cglib implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("租房前看房源");
        Object res = methodProxy.invokeSuper(o, objects);
        System.out.println("租房后签合同");
        return res;
    }
}

3.修改Customer类

        Cglib cglib= new Cglib();
        Enhancer enhancer = new Enhancer();
         // 设置代理类的父类
        enhancer.setSuperclass(Homeowners.class);
         // 设置回调对象
        enhancer.setCallback(cglib);
         // 创建被代理对象
        Homeowners homeowners = (Homeowners) enhancer.create();
        homeowners.renting();
上一篇 下一篇

猜你喜欢

热点阅读