【设计模式】Java设计模式 - 责任链模式

简介: 拦截器可以拦截目标方法,进行一系列的操作。也可以取代代理对象的方法等功能。以下代码用JDK动态代理来实现一个拦截器的逻辑。

Java设计模式 - 责任链模式

😄 不断学习才是王道
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 关注我的CSDN: 一个有梦有戏的人
👊 打算连载Java设计模式,记录自己的学习心得,分享学习经验。

拦截器

拦截器可以拦截目标方法,进行一系列的操作。也可以取代代理对象的方法等功能。以下代码用JDK动态代理来实现一个拦截器的逻辑。

1、接口提供

首先提供方法接口和实现类作为动态代理拦截的方法

package com.lyd.demo.service;

/**
 * @Author: lyd
 * @Description: 普通的接口
 * @Date: 2022-08-19
 */
public interface HelloWorldService {
    public void sayHelloWorld(String name);
}

实现类

package com.lyd.demo.service.impl;

import com.lyd.demo.service.HelloWorldService;

/**
 * @Author: lyd
 * @Description: 接口实现
 * @Date: 2022-08-19
 */
public class HelloWorldServiceImpl implements HelloWorldService {
    @Override
    public void sayHelloWorld(String name) {
        System.out.println("Hello World! " + name);
    }
}

2、定义拦截器接口Interceptor

这里定义了三个方法:before、around、after,都有:代理对象 proxy, 真实对象 target, 方法 method, 参数 args

  • before方法返回的是Boolean,在真实对象前调用。
  • 返回true时,反射真实对象的方法,false时,调用around方法

最后执行after方法

package com.lyd.demo.interceptor;

import java.lang.reflect.Method;

/**
 * @Author: lyd
 * @Description: 拦截器接口
 * @Date: 2022-08-17
 */
public interface Interceptor {
    public boolean before(Object proxy, Object target, Method method, Object[] args);

    public void around(Object proxy, Object target, Method method, Object[] args);

    public void after(Object proxy, Object target, Method method, Object[] args);
}

3、定义拦截器实现类

package com.lyd.demo.impl;

import com.lyd.demo.interceptor.Interceptor;

import java.lang.reflect.Method;

/**
 * @Author: lyd
 * @Description: 实现拦截接口
 * @Date: 2022-08-17
 */
public class MyInterceptor implements Interceptor {
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("反射方法前逻辑");
        return false; // 不反射被代理对象原有方法
    }

    public void around(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("取代了代理对象的方法");
    }

    public void after(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("反射方法后逻辑");
    }
}

4、采用JDK动态代理的方式使用拦截器

构建jdk代理:

package com.lyd.demo.jdk;

import com.lyd.demo.interceptor.Interceptor;

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

/**
 * @Author: lyd
 * @Description: JDK动态代理使用拦截器
 * @Date: 2022-08-17
 */
public class InterceptorJdkProxy implements InvocationHandler {

    private Object target; // 真实对象
    private String interceptorClass = null; // 拦截器全限定名

    public InterceptorJdkProxy(Object target, String interceptorClass) {
        this.target = target;
        this.interceptorClass = interceptorClass;
    }

    /**
     * 绑定委托对象并返回一个【代理占位】
     * @param target 真实对象
     * @return 代理对象
     */
    public static Object bind(Object target, String interceptorClass) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InterceptorJdkProxy(target, interceptorClass));
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (interceptorClass == null) {
            // 没有设置拦截器则直接反射原有方法
            return method.invoke(proxy, args);
        }
        Object result = null;
        // 通过反射生成拦截器
        Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance();
        // 调用前置方法
        if (interceptor.before(proxy, target, method, args)) {
            //反射原有方法
            return method.invoke(target, args);
        } else { // 返回false方法执行around方法
            interceptor.around(proxy, target, method, args);
        }
        // 调用后置方法
        interceptor.after(proxy, target, method, args);
        return result;
    }
}

5、实例

测试:

package com.lyd.demo.test;

import com.lyd.demo.jdk.InterceptorJdkProxy;
import com.lyd.demo.service.HelloWorldService;
import com.lyd.demo.service.impl.HelloWorldServiceImpl;

/**
 * @Author: lyd
 * @Description: 测试类
 * @Date: 2022-08-19
 */
public class InterceptorTest {
    public static void main(String[] args) {
        HelloWorldService proxy = (HelloWorldService) InterceptorJdkProxy.bind(new HelloWorldServiceImpl(), "com.lyd.demo.impl.MyInterceptor");
        proxy.sayHelloWorld("lyd");

    }
}

结果:
image.png

责任链模式

当一个对象在一条链上被多个拦截器拦截处理,当然也可以不拦截处理,这种的设计模式就是责任链模式。可以在这被拦截的期间进行加工处理。就好比如,我们申请请假,需要经过项目经理,再到部门经理,最后到人事。在这期间,经理审批时候可以修改请假天数。本次实验用以上部分代码。

1、定义拦截器

这里定义三个拦截器分别是三个类

package com.lyd.demo.impl;

import com.lyd.demo.interceptor.Interceptor;

import java.lang.reflect.Method;

/**
 * @Author: lyd
 * @Description: 责任链 - 拦截器1
 * @Date: 2022-08-20
 */
public class Interceptor1 implements Interceptor {
    @Override
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("拦截器1的before");
        return true;
    }

    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {

    }

    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
        System.out.println("拦截器1的after");
    }
}

拦截器2,3也是如此就不粘贴代码了。

2、责任链上使用拦截器实例

测试:

package com.lyd.demo.test;

import com.lyd.demo.jdk.InterceptorJdkProxy;
import com.lyd.demo.service.HelloWorldService;
import com.lyd.demo.service.impl.HelloWorldServiceImpl;

/**
 * @Author: lyd
 * @Description: 责任链模式测试
 * @Date: 2022-08-20
 */
public class ResponsibilityChainTest {
    public static void main(String[] args) {
        HelloWorldService proxy1 = (HelloWorldService) InterceptorJdkProxy.bind(new HelloWorldServiceImpl(), "com.lyd.demo.impl.Interceptor1");

        HelloWorldService proxy2 = (HelloWorldService) InterceptorJdkProxy.bind(proxy1, "com.lyd.demo.impl.Interceptor2");

        HelloWorldService proxy3 = (HelloWorldService) InterceptorJdkProxy.bind(proxy2, "com.lyd.demo.impl.Interceptor3");

        proxy3.sayHelloWorld("怒放吧德德");
    }
}

运行结果:
image.png

相关文章
|
5天前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
4月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
105 0
|
7月前
|
设计模式 存储 Java
「全网最细 + 实战源码案例」设计模式——责任链模式
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,允许将请求沿着处理者链进行发送。每个处理者可以处理请求或将其传递给下一个处理者,从而实现解耦和灵活性。其结构包括抽象处理者(Handler)、具体处理者(ConcreteHandler)和客户端(Client)。适用于不同方式处理不同种类请求、按顺序执行多个处理者、以及运行时改变处理者及其顺序的场景。典型应用包括日志处理、Java Web过滤器、权限认证等。
144 13
「全网最细 + 实战源码案例」设计模式——责任链模式
|
6月前
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
|
10月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
165 6
|
10月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
138 4
|
10月前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
80 0
|
10月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
453 0
|
10月前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
79 0
|
11月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
本教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速上手Kotlin的读者,推荐查阅“简洁”系列教程。本文通过学生会经费申请的例子,介绍了责任链模式及其在Kotlin中的实现,并使用偏函数进行了改进,使代码更加简洁和灵活。
69 0