Java代理模式——静态代理与动态代理

简介: Java代理模式——静态代理与动态代理

代理模式

代理模式允许你为其他对象提供一个代理,以控制对这个对象的访问。代理模式在不改变实际对象的情况下,可以在访问对象时添加额外的功能。

可以理解为代理模式为被代理对象创造了一个替身,调用者可以通过这个替身去实现这个被代理对象的功能,这个替身也可以为被代理对象增加功能

静态代理

定义

使用时候需要定义接口或者父类。 代理类和委托类有共同的父类或父接口。

案例

首先定义一个接口 ITeacherDao,并在这个接口中定义一个teacher()方法。

package Static;
 
public interface ITeacherDao {
    void teacher();
}

再写一个他的实现类,实现teacher()方法

package Static;
 
public class TeacherDao implements ITeacherDao{
    @Override
    public void teacher() {
        System.out.println("老师在教课");
    }
}

如上,我们实现了一个简单接口与他的实现类,接下来我们实现一个老师的静态代理类

package Static;
 
public class TeacherDaoProxy implements ITeacherDao{
 
    private TeacherDao teacherDao;
 
    public TeacherDaoProxy(TeacherDao teacherDao){
        this.teacherDao = teacherDao;
    }
    @Override
    public void teacher() {
        System.out.println("代理前");
        teacherDao.teacher();
        System.out.println("代理后");
    }
}

在这段代码中,我们实现了TeacherDao的代理类,并通过调用teacherDao这个对象使用了被代理对象的方法;我们在使用被代理对象方法前后都拓展了新的功能,这就是静态代理。

下面是主函数对于静态代理的使用

public class Main {
    public static void main(String[] args) {
        Static.TeacherDao teacherDao = new TeacherDao();
 
        TeacherDaoProxy teacherDaoProxy = new TeacherDaoProxy(teacherDao);
 
        teacherDaoProxy.teacher();
    }
}

这说明我们的代理类在实现被代理对象的功能时也拓展了新的功能

但是,这样的模式也存在一种缺陷,就是我们的代理对象和被调用对象都要实现同一接口或父类,可能会出现多个代理类,接口如果要增加方法的话会有很多代理类需要维护;针对这一问题,Java的开发者定义了相关方法去解决,这就是我们下面要介绍的被代理类。

动态代理

定义

不需要实现接口,但是被代理的目标对象需要实现,调用jdk的api形成代理对象,

动态代理就是通过使用反射,动态地获取抽象接口的类型,从而获取相关特性进行代理。

案例

我们还是先定义一个接口

public interface ITeacherDao {
    void teacher();
    void sayhello();
}

接着我们定义他的实现类

public class TeacherDao implements ITeacherDao {
    @Override
    public void teacher() {
        System.out.println("老师在教课");
    }
 
    @Override
    public void sayhello() {
        System.out.println("hello");
    }
}

接着我们实现一个动态的代理类,可以动态代理原对象;在这个代理类中,我们使用到了Proxy.newProxyInstance 这个函数,他有三个参数,以下是三个参数的解释

1.target.getClass().getClassLoader():获取被代理对象的类加载器。这是用于加载代理类的类加载器。

2.target.getClass().getInterfaces():获取被代理对象实现的接口。这些接口是代理类将要实现的接口。

3.new InvocationHandler() { ... }:创建一个匿名的 InvocationHandler 对象,它实现了 invoke 方法,这是代理逻辑的核心部分。

我们在InvocationHandler() { ... }中调用了被代理对象的方法,并且做了一些扩展

public class FactoryProxy  {
    private Object target;
 
    public FactoryProxy(Object target){
        this.target = target;
    }
 
    public Object getProxyIstance() {
        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("代理前");
                Object returnVal = method.invoke(target,args);
                System.out.println("代理后");
 
                return returnVal;
            }
        });
    };
}

在主函数中调用被代理类,创建一个接口类,讲接口类传入被代理类,然后就可以定义接口类中的方法了,即实现了动态代理。

public class Main {
    public static void main(String[] args) {
        ITeacherDao iteacherDao = new TeacherDao();
 
        ITeacherDao proxyInstance = (ITeacherDao) new FactoryProxy(iteacherDao).getProxyIstance();
 
        proxyInstance.teacher();
        proxyInstance.sayhello();
 
    }
}

最终输出结果

可以看出,我们通过动态代理类实现了对目标对象的功能拓展

链接

java静态代理与动态代理: java静态代理与动态代理

目录
相关文章
|
3天前
|
设计模式 Java 索引
由反射引出的Java动态代理与静态代理
由反射引出的Java动态代理与静态代理
12 0
|
8天前
|
存储 Java
Java动态转发代理IP的实现方法
Java动态转发代理IP的实现方法
23 11
|
8天前
|
监控 Java 开发者
掌握 Java 反射和动态代理
【4月更文挑战第19天】Java反射和动态代理提供强大功能和灵活性。反射允许运行时检查和操作类,获取类信息、动态调用方法,但可能带来性能损失和降低代码可读性。动态代理则用于创建代理对象,实现透明性和横切关注点分离,常用于日志、权限检查等。两者结合能实现更复杂功能。掌握这些技术能提升代码的灵活性和可扩展性,但也需注意性能和可读性。通过学习和实践,能更好地构建高效软件系统。
|
9天前
|
安全 Java API
java借助代理ip,解决访问api频繁导致ip被禁的问题
java借助代理ip,解决访问api频繁导致ip被禁的问题
|
Java
Java学习路线-57:静态代理和动态代理
Java学习路线-57:静态代理和动态代理
86 0
Java学习路线-57:静态代理和动态代理
Java学习路线-57:静态代理和动态代理
|
Java
Java学习路线-57:静态代理和动态代理
Java学习路线-57:静态代理和动态代理
83 0
|
4天前
|
安全 Java 调度
Java线程:深入理解与实战应用
Java线程:深入理解与实战应用
24 0
|
1天前
|
缓存 Java
Java并发编程:深入理解线程池
【4月更文挑战第26天】在Java中,线程池是一种重要的并发工具,它可以有效地管理和控制线程的执行。本文将深入探讨线程池的工作原理,以及如何使用Java的Executor框架来创建和管理线程池。我们将看到线程池如何提高性能,减少资源消耗,并提供更好的线程管理。
|
2天前
|
消息中间件 缓存 NoSQL
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度
Java多线程实战-CompletableFuture异步编程优化查询接口响应速度