Titan笔记

  • 首页
  • Java
  • 数据结构
  • Web
  • C语言
  • Python
  • 杂谈
  • 逸笔挥墨
Titan笔记
分享学习、研究与开发过程中的点滴记忆
  1. 首页
  2. Java
  3. 正文

Java核心技术之动态代理

2020年4月21日 311点热度 2人点赞 0条评论

提出一个问题

在实际的编程过程中,你可能会遇到这样的问题。你拥有以下的业务逻辑:A, B 和 C,在最初的设计过程中,你的程序在执行B之前,要先执行A,在执行B之后,要紧接着最后执行C。可是随着业务的调整,你不想在B之前执行A了,甚至想重新增加一个D来替换A。有没有不修改代码的前提下动态的进行这样的逻辑调整?动态代理就可以用来解决这个问题。

什么是动态代理

Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface的实例。

使用动态代理,一般是为了给需要实现的方法添加预处理或者添加后续操作,但是不干预实现类的正常业务,把一些基本业务和主要的业务逻辑分离。

23种设计模式中的面向切面编程 (AOP) 就是以动态代理机制基础的。

基于JDK的动态代理如何实现

首先定义一个接口

package ProxyStudy;

public interface Hello {
    public void sayHello();
}

然后编写这个接口的实现类

package ProxyStudy;

public class Helloer implements Hello {
    @Override
    public void sayHello() {
        System.out.println("Helloer says: Hello!");
    }
}

在静态实现的过程中,你一定会这样做

        Helloer helloer = new Helloer();
        helloer.sayHello();

但是在动态代理中,首先要定义一个 ProxyHandler 类,并实现 InvocationHandler 接口。

package ProxyStudy;

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

public class ProxyHandler implements InvocationHandler {
    private Object subject;

    public ProxyHandler(Object subject) {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("I am ready to do something...");
        Object invoker = method.invoke(subject, args);
        System.out.println("I am done~");
        return invoker;
    }
}

这样,你就可以通过Proxy来动态生成一个代理对象,然后通过调用这个代理对象来实现真正对象的方法。实际上调用的是代理对象的invoke方法。

package ProxyStudy;

import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        // 创建目标对象
        Hello hello = new Helloer();
        // 创建调用处理器对象
        ProxyHandler proxyHandler = new ProxyHandler(hello);
        // 动态生成代理对象
        Hello helloProxy = (Hello) Proxy.newProxyInstance(
                Helloer.class.getClassLoader(), Helloer.class.getInterfaces(), proxyHandler);
        // 通过代理对象调用方法
        helloProxy.sayHello();
    }
}

实际的输出:

动态代理的意义

如上面的代码,你可以把“I am ready to do something”替换成一些执行真正方法前要进行的东西,把“I am done” 替换成一些执行真正方法后要进行的“收尾”工作的东西。动态代理使得在不修改业务类的情况下,能很方便的增加一些其他操作。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: Java Java动态代理
最后更新:2020年4月21日

Titan

兴趣广泛而无一精擅
想到什么,我总是渴望以代码的方式去呈现
永远年轻,永远热泪盈眶
Stay Hungry, Stay Foolish

点赞
< 上一篇
下一篇 >

文章评论

取消回复

Titan

兴趣广泛而无一精擅
想到什么,我总是渴望以代码的方式去呈现
永远年轻,永远热泪盈眶
Stay Hungry, Stay Foolish

逸笔挥墨 - Titan的文学天地
文章分类
  • C语言 (4)
  • Hadoop (1)
  • Hive (3)
  • Java (19)
  • JavaWeb (4)
  • Linux运维之道 (1)
  • Mybatis学习笔记 (3)
  • Python (3)
  • SpringCloud (4)
  • Web (5)
  • Web前端 (4)
  • Web后端 (5)
  • 数据库 (1)
  • 数据结构 (10)
  • 杂谈 (3)
  • 诗词歌赋 (1)
  • 随摘 (2)
最新 热点 随机
最新 热点 随机
Spring Cloud 微服务学习笔记 - 负载均衡服务调用 Spring Cloud 微服务学习笔记 - Eureka 服务注册与发现 Spring Cloud 微服务学习笔记 - IDEA工程搭建 关于我和Titan笔记 Spring Cloud 微服务学习笔记 - 开篇 TitanEMS - Titan企业员工管理系统 - JavaWeb期末实践项目
Spring Cloud 微服务学习笔记 - 开篇TitanEMS - Titan企业员工管理系统 - JavaWeb期末实践项目2021年1月随摘2021年1月诗摘关于我和Titan笔记《梦之浮桥》中的几句
[数据结构] 使用最小堆思想实现哈夫曼编解码 Titan商店 - 又一个Web静态项目 Apache-Hive 使用MySQL存储Hive的元数据 [数据结构]链式存储: 多项式求和 Linux 网络优化指南 - 改善Linux的网络性能 [Java] 日期与时间的一些操作
标签聚合
链式存储 Mybatis学习笔记 Python Apache-Hive 二叉树 Java JavaWeb 数据结构
友情链接
  • Mttblog

COPYRIGHT © 2016 - 2021 Titan笔记. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

豫ICP备20001822号-1

豫公网安备 41010502004418号