架构系列——java动态代理中的InvocationHandler和Proxy

简介: 架构系列——java动态代理中的InvocationHandler和Proxy

前言

先赞后看,此生必赚!

Java中动态代理的实现,主要是InvocationHandler和Proxy的使用。

可以通过以下步骤实现一个动态代理:

一、创建正常的接口以及实现类

1. 接口:

public interface People {
  public void working();
}

2. 实现类:

public class Student implements People {
  @Override
  public void work() {
    System.out.println("正在学习...");
  }
}

二、创建一个PeopleHandler实现InvocationHandler

public class PeopleHandler implements InvocationHandler {
  private Object obj;
  public PeopleHandler(Object obj) {
    this.obj = obj;
  }
  public Object getProxy(Object obj) {
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("before invoke...");
    Object result = method.invoke(obj, args);
    System.out.println("after invoke...");
    return result;
  }
}u

解读:

PeopleHandler(Object obj):通过被代理对象创建handler;


getProxy(Object obj):通过被代理对象创建代理;


invoke(Object proxy, Method method, Object[] args):代理不直接调用invoke,而是使用正常的方法时都会走invoke方法;

三、调用方法

可以使用两种方式调用方法:

1. 直接调用

不使用代理类直接调用,直接实现业务逻辑

2. 使用代理类调用

使用代理类调用,间接实现业务逻辑

public class TestProxy {
  public static void main(String[] args) {
    //1.直接调用
    System.out.println("直接调用:");
    People people = new Student();
    people.work();
    //2.通过代理调用
    System.out.println("\n通过代理调用:");
    PeopleHandler handler = new PeopleHandler(people);
    People proxy = (People) handler.getProxy(people);
    proxy.work();
  }
}

结果:

直接调用:
正在学习...
通过代理调用:
before invoke...
正在学习...
after invoke...

四、总结

1. 使用代理的好处

从上面的案例可以看出,两者都可以实现正常的业务逻辑,那为啥要多此一举地使用代理类呢?

1.1 降低耦合度

正常逻辑work()与日志的关系没那么强烈,可以对业务逻辑的各个部分进行隔离。


1.2 提高可重用性

如果不使用代理,需要每一次在调用work()前后都要写日志,这样的话,代码的可重用性为0!


使用代理之后,只需要在handler的invoke()方法中写一次即可,重用性明显提高!


2. 使用场景

除了上面案例中的日志,还有性能统计,安全控制,事务处理,异常处理等等。


安全控制举例:


校验用户权限,每一个菜单请求,都要判断一下请求的用户是否有该菜单权限。菜单多了,代码冗余,且容易遗漏。


通过动态代理就可以实现为:每一个用户,每一个菜单的请求,都经过代理(proxy),由他判断是否有权限,调用者只需要调用,实现自己的逻辑,不关心权限问题。


相关文章
|
23天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
67 10
|
25天前
|
设计模式 Java API
[Java]静态代理与动态代理(基于JDK1.8)
本文介绍了代理模式及其分类,包括静态代理和动态代理。静态代理分为面向接口和面向继承两种形式,分别通过手动创建代理类实现;动态代理则利用反射技术,在运行时动态创建代理对象,分为JDK动态代理和Cglib动态代理。文中通过具体代码示例详细讲解了各种代理模式的实现方式和应用场景。
23 0
[Java]静态代理与动态代理(基于JDK1.8)
|
2月前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
415 37
|
1月前
|
Java
深入理解Java动态代理
深入理解Java动态代理
19 1
|
29天前
|
Java
Java代码解释静态代理和动态代理的区别
### 静态代理与动态代理简介 **静态代理**:代理类在编译时已确定,目标对象和代理对象都实现同一接口。代理类包含对目标对象的引用,并在调用方法时添加额外操作。 **动态代理**:利用Java反射机制在运行时生成代理类,更加灵活。通过`Proxy`类和`InvocationHandler`接口实现,无需提前知道接口的具体实现细节。 示例代码展示了两种代理方式的实现,静态代理需要手动创建代理对象,而动态代理通过反射机制自动创建。
|
2月前
|
设计模式 架构师 Java
Java开发工程师转架构师需要学习什么
Java开发工程师转型为架构师需掌握多项技能:精通Java及框架、数据库与分布式系统;熟悉设计模式与架构模式;积累项目经验;提升沟通与领导力;持续学习新技术;培养系统设计与抽象能力;了解中间件及开发工具;并注重个人特质与职业发展。具体路径应结合个人目标与实际情况制定。
68 18
|
2月前
|
Kubernetes Java Android开发
用 Quarkus 框架优化 Java 微服务架构的设计与实现
Quarkus 是专为 GraalVM 和 OpenJDK HotSpot 设计的 Kubernetes Native Java 框架,提供快速启动、低内存占用及高效开发体验,显著优化了 Java 在微服务架构中的表现。它采用提前编译和懒加载技术实现毫秒级启动,通过优化类加载机制降低内存消耗,并支持多种技术和框架集成,如 Kubernetes、Docker 及 Eclipse MicroProfile,助力开发者轻松构建强大微服务应用。例如,在电商场景中,可利用 Quarkus 快速搭建商品管理和订单管理等微服务,提升系统响应速度与稳定性。
70 5
|
1月前
|
设计模式 缓存 Java
从源码学习Java动态代理|8月更文挑战
从源码学习Java动态代理|8月更文挑战
|
2月前
|
Java API 开发者
【Java模块化新飞跃】JDK 22模块化增强:构建更灵活、更可维护的应用架构!
【9月更文挑战第9天】JDK 22的模块化增强为开发者构建更灵活、更可维护的应用架构提供了强有力的支持。通过模块化设计、精细的依赖管理和丰富的工具支持,开发者可以更加高效地开发和管理应用,提高应用的性能和可维护性。
87 10
|
2月前
|
存储 缓存 Java
JAVA并发编程系列(11)线程池底层原理架构剖析
本文详细解析了Java线程池的核心参数及其意义,包括核心线程数量(corePoolSize)、最大线程数量(maximumPoolSize)、线程空闲时间(keepAliveTime)、任务存储队列(workQueue)、线程工厂(threadFactory)及拒绝策略(handler)。此外,还介绍了四种常见的线程池:可缓存线程池(newCachedThreadPool)、定时调度线程池(newScheduledThreadPool)、单线程池(newSingleThreadExecutor)及固定长度线程池(newFixedThreadPool)。