设计模式——代理模式

静态代理

例子:有一个教师类,教师类有一个教书方法

需要使用一个代理类来代理教师,将教师类聚合到代理类里面

具体代码如下:

首先创建一个接口,不仅教师类需要实现,代理类也需要实现,但是注意的是,代理类实现的时候,是使用的教师类的教书方法。

java 复制代码
package com.StaticProxy;

//代理模式
public interface ITeacherDao {
    void teach();
}
java 复制代码
package com.StaticProxy;

//真正的实体对象,需要被代理的类
//该类中有真正的教书方法
public class TeacherDao implements ITeacherDao {

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void teach() {
        System.out.println(this.name + "在教书");

    }
}
java 复制代码
package com.StaticProxy;

//代理,需要代理TeacherDao,它虽然有teach方法,但是不是真的会教书,所以需要调用TeacherDao的教书方法
public class TeacherDaoProxy implements ITeacherDao{
    private ITeacherDao teacherDao;

    public TeacherDaoProxy(ITeacherDao teacherDao) {
        this.teacherDao = teacherDao;
    }

    @Override
    public void teach() {
        System.out.println("通过代理对象。。。");
        System.out.println("代理使用真实的teacherDao在教书");
        teacherDao.teach();
        System.out.println("代理结束");
    }
}

使用代理类:

java 复制代码
package com.StaticProxy;

public class Client {
    public static void main(String[] args) {
        //新建一个TeacherDAO类
        TeacherDao teacherDao = new TeacherDao();
        teacherDao.setName("lisi");

        //使用一个代理类来代理教师类
        TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
        teacherDaoProxy.teach();
    }
}

因为是静态代理,所以就是教师代理类,要是换一个需要代理的类,就不能实现了。一次引入动态代理。

动态代理

使用一个proxyFactory,传入一个Target目标对象,动态生成对应的目标代理对象。

首先需要一个目标对象类的接口。

java 复制代码
package com.DynamicProxy;

public interface ITeacherDao {
    void teach();
}

目标对象类实现这个接口。

java 复制代码
package com.DynamicProxy;

public class TeacherDao implements ITeacherDao{
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void teach() {
        System.out.println(this.name + "在教书");
    }
}

动态代理工厂

在该类中,使用Proxy.newProxyInstance,生成代理对象,这个方法有3个参数:

  1. ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
  2. Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
  3. InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入
java 复制代码
package com.DynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {

    //维护一个目标对象,object  这里相当于TeacherDao了
    private Object target;

    //构造器,对target进行初始化
    public ProxyFactory(Object target){
        this.target = target;
    }

    //给目标对象 生成一个代理对象

//    ClassLoader loader :当前目标对象使用的类加载器,获取加载器的方法固定
//    Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
//    InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器方法,会把当前执行的目标对象方法作为一个参数传入
    public Object getProxyInstance(){

        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("jdk代理开始---");
                        //反射机制调用目标对象的方法
                        Object returnVal = method.invoke(target, args);
                        return returnVal;
                    }
                });
    }
}
java 复制代码
package com.DynamicProxy;

import com.DynamicProxy.TeacherDao;

public class Client {
    public static void main(String[] args) {
        //目标对象
//        ITeacherDao teacherDao = new TeacherDao();
        TeacherDao teacherDao = new TeacherDao();
        teacherDao.setName("lisi");

        //使用代理工厂 给目标对象创建代理对象
        ProxyFactory proxyFactory = new ProxyFactory(teacherDao);
        //强转成ITeacherDao类型 否则没办法调用教书方法
        ITeacherDao proxyInstance =(ITeacherDao) proxyFactory.getProxyInstance();
        //proxyInstance : class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
        proxyInstance.teach();
    }
}
相关推荐
缘来是庄8 小时前
设计模式之访问者模式
java·设计模式·访问者模式
hqxstudying10 小时前
Java创建型模式---单例模式
java·数据结构·设计模式·代码规范
花好月圆春祺夏安12 小时前
基于odoo17的设计模式详解---装饰模式
数据库·python·设计模式
fie888912 小时前
浅谈几种js设计模式
开发语言·javascript·设计模式
哆啦A梦的口袋呀12 小时前
《深入设计模式》模式结构汇总
设计模式
花好月圆春祺夏安12 小时前
基于odoo17的设计模式详解---单例模式
单例模式·设计模式
在未来等你15 小时前
设计模式精讲 Day 22:模板方法模式(Template Method Pattern)
设计模式·模板方法模式·软件架构·java开发·面向对象设计·设计模式实战·java应用开发
花好月圆春祺夏安16 小时前
基于odoo17的设计模式详解---代理模式
设计模式·代理模式
Small black human1 天前
设计模式-应用分层
设计模式
码农秋2 天前
设计模式系列(10):结构型模式 - 桥接模式(Bridge)
设计模式·桥接模式