常用工厂设计模式之代理模式---用几个demo就能理解的代理模式


首先我们要知道,工厂设计模式分为三类:创建型模式、行为型模式、结构型模式
代理模式属于结构型


一、什么是代理

代理模式(Proxy Pattern):一个类代表另一个类的功能

很难懂?

其实用现实生活的话说,简单理解代理就是中介,而代理又分为静态代理动态代理

但是不管哪种代理都遵循一个前提:

代理要求代理类和被代理类(即目标类)要有共同的行为

那问题又来了,什么又是代理类与目标类的共同行为

我来告诉你:

  • 代理类与目标类实现同一个接口
  • 代理类继承目标类

诶,你会发现了,实现接口和继承,不就是多态的体现吗?

没错,说白了就是通过代理类实现目标类里面的方法

下面用几个简单的demo来演示一下


二、静态代理

静态代理:代理类在程序运行之前由程序员在开发过程已经写好了

1、代理类和目标类实现同一个接口

建一个接口

public interface Subject {
    public void chuzu();
}

建一个目标类

public class Fangdong implements Subject {
    @Override
    public void chuzu() {
        System.out.println("房屋出租,2000一个月");
    }
}

建一个代理类

public class Zhongjie implements Subject{
    //目标类的引用
    Fangdong fangdong = new Fangdong();
    @Override
    public void chuzu() {
        System.out.println("发布广告");
        System.out.println("带客户看房");
        //调用目标类方法
        fangdong.chuzu();
        System.out.println("另收中介费500");
    }
}

测试

public class demo1 {
    @Test
    public void test(){
        Subject subject = new Zhongjie();
        subject.chuzu();
    }
}

运行结果

在这里插入图片描述

2、代理类继承目标类

修改一下代理类

public class Zhongjie extends Fangdong{
    @Override
    public void chuzu() {
        System.out.println("发布广告");
        System.out.println("带客户看房");
        //直接调用父类(目标类)方法
        super.chuzu();
        System.out.println("另收中介费500");
    }
}

修改一下目标类

public class Fangdong  {
    public void chuzu() {
        System.out.println("房屋出租,2000一个月");
    }
}

测试

public class demo1 {
    @Test
    public void test(){
        Zhongjie zhongjie = new Zhongjie();
        zhongjie.chuzu();
    }
}

运行结果

在这里插入图片描述


三、动态代理

动态代理:代理类由程序运行过程中态动生成的

1、目标类实现接口—jdk代理

接口

public interface PersonService {

    public void insert();

    public void update();

    public void delete();
}

目标类实现接口

public class PersonServiceImpl implements PersonService{
    @Override
    public void update() {
        System.out.println("执行数据库增加操作");
    }

    @Override
    public void delete() {
        System.out.println("执行数据库删除操作");
    }

    @Override
    public void insert() {
        System.out.println("执行数据库修改操作");
    }
}

JdkProxy代理类(这里相对比较难理解)

public class JdkProxy implements InvocationHandler {
    //程序运行中为多个目标类创建对应代理类

    private Object target;

    //获取目标类
    public JdkProxy(Object target){
        this.target = target;

    }

    //为具体某一个目标类创建具体的代理类
    public Object createProxy(){
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
        //最后一个参数应该传一个InvocationHandler对象,
        //为什么这里直接用this,因为JdkProxy本身就是实现InvocationHandler接口,所以这里传它自己
        return proxy;
    }

    @Override
    //编写代理类具体的工作流程
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //权限校验
        System.out.println("权限校验");
        //执行目标类的方法
        Object invoke = method.invoke(target, args);
        //日志记录
        System.out.println("日志记录");
        return invoke;
    }
}

测试

public class demo2 {
    @Test
    public void test2(){
        JdkProxy jdkProxy = new JdkProxy(new PersonServiceImpl());
        PersonService proxy = (PersonService) jdkProxy.createProxy();
        proxy.update();
    }
}

运行结果

在这里插入图片描述

2、目标类没有实现接口—cglib代理

目标类

public class PersonServiceImpl {

    public void update() {
        System.out.println("执行数据库增加操作");
    }

    public void delete() {
        System.out.println("执行数据库删除操作");
    }

    public void insert() {
        System.out.println("执行数据库修改操作");
    }
}

cglib代理类

public class CglibProxy implements InvocationHandler {
    private Object target;

    //获取到了目标类
    public CglibProxy(Object target){
        this.target = target;
    }

    //根据目标类创建代理类
    public Object createProxy(){
        //使用cglib中的字节码增强类
        Enhancer enhancer = new Enhancer();
        //代理类需要和目标类有一样的方法
        //代理类继承目标类
        enhancer.setSuperclass(target.getClass());
        //设置代理规则
        //因为InvocationHandler 继承了callback接口
        //因此当前的规则对象 其实就是 Callback类型的
        enhancer.setCallback(this);
        //创建代理对象
        return enhancer.create();
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("cglib权限校验");
        //执行目标类的方法
        Object invoke = method.invoke(target, objects);
        System.out.println("cglib日志记录");
        return invoke;
    }
}

测试

@Test
    public void test(){
        CglibProxy cglibProxy = new CglibProxy(new PersonServiceImpl());
        PersonServiceImpl proxy = (PersonServiceImpl) cglibProxy.createProxy();
        proxy.update();
    }

运行结果

在这里插入图片描述


四、由程序自己动态生成的代理类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.sun.proxy;

import com.ujiuye.demo5.PersonService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements PersonService {
    private static Method m1;
    private static Method m5;
    private static Method m2;
    private static Method m4;
    private static Method m0;
    private static Method m3;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void save() throws  {
        try {
            super.h.invoke(this, m5, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void delete() throws  {
        try {
            super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void update() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m5 = Class.forName("com.ujiuye.demo5.PersonService").getMethod("save");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m4 = Class.forName("com.ujiuye.demo5.PersonService").getMethod("delete");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m3 = Class.forName("com.ujiuye.demo5.PersonService").getMethod("update");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

版权声明:本文为weixin_46816383原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。