千家信息网

java设计模式中的责任链模式是什么

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇文章为大家展示了java设计模式中的责任链模式是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一:模式说明模式定义:使多个对象都有机会处理请求,从而避
千家信息网最后更新 2026年11月01日java设计模式中的责任链模式是什么

本篇文章为大家展示了java设计模式中的责任链模式是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。


一:模式说明

模式定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

责任链模式的重点是在"链"上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果(取自《设计模式之禅》)。

翻译:Client对象调用一个处理者(类)的方法,可能有多个处理者(实现类),但是该对象只需要调用第一个处理者(类)即可,该模式会自动分配谁来处理这个请求;这多个处理者继承同一个父类(即在一条链上)。

通用类图如下:

Client发送请求到Handler,Handler自动分配请求到子类的实现类ConcreteHandler中。

二:项目实战

在文章 >手写redis@Cacheable注解 支持过期时间设置< 的基础之上做修改,原版为redis缓存注解实现,

原版实现功能:

  • 将数据存放到redis中

  • 设置过期时间

原业务逻辑查询人员列表listleader()接口,数据存放redis中,减少数据库负载。

由于业务发展,需要进一步优化查询接口;目前每个人都会操作redis中存放的人员列表,导致该列表会实时发生变动(比如

每个人员对应的分数),每个人都有自己的缓存人员列表而不是统一的人员列表;原列表已经无法满足现需求,每个人第一次登

录都会查询数据库,将自己的列表存放在redis中。

解决方法:设置两级缓存,第一级为该用户(uuid)唯一缓存,key值设置为参数1+uuid+参数2;第二级为第一次登录查询返

回redis中的原始leader列表,key值设置为参数1+参数2。如果当前用户leader列表(一级缓存)为空,则查询原始leader列表

(二级缓存),在操作分数的时候修改二级缓存(初始人员列表)来产生一级缓存,存放进redis,减少了数据库的直接访问。

项目中责任链相关设计类图如下:

说明:抽象类CacheHandler 一是定义了处理请求方法handleMessage;二是定义一个链的编排方法setNext,设置下一个处理者;三是定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别getHandlerLevel和具体的处理任务response;

FirstCacheHadler为一级缓存处理者,SecondCacheHadler为二级缓存处理者。缓存处理的方式通过CacheableAspect类调用。

三:源代码

CacheableAspect:client调用

package com.huajie.aspect; import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.huajie.annotation.ExtCacheable;import com.huajie.common.cache.CacheHandler;import com.huajie.common.cache.FirstCacheHadler;import com.huajie.common.cache.RedisResult;import com.huajie.common.cache.SecondCacheHadler;import com.huajie.utils.RedisUtil;import com.huajie.utils.StringUtil; /** * redis缓存处理 不适用与内部方法调用(this.)或者private */@Component@Aspectpublic class CacheableAspect {         @Autowired        private RedisUtil redisUtil;         @Pointcut("@annotation(com.huajie.annotation.ExtCacheable)")        public void annotationPointcut() {        }         @Around("annotationPointcut()")        public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {                // 获得当前访问的class                Class className = joinPoint.getTarget().getClass();                // 获得访问的方法名                String methodName = joinPoint.getSignature().getName();                // 得到方法的参数的类型                Class[] argClass = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();                Object[] args = joinPoint.getArgs();                String key = "";                String nextKey = "";                int expireTime = 1800;                try {                        // 得到访问的方法对象                        Method method = className.getMethod(methodName, argClass);                        method.setAccessible(true);                        // 判断是否存在@ExtCacheable注解                        if (method.isAnnotationPresent(ExtCacheable.class)) {                                ExtCacheable annotation = method.getAnnotation(ExtCacheable.class);                                key = getRedisKey(args, annotation.key());                                nextKey = getRedisKey(args,annotation.nextKey());                                expireTime = getExpireTime(annotation);                        }                } catch (Exception e) {                        throw new RuntimeException("redis缓存注解参数异常", e);                }                //责任链模式                CacheHandler firstCacheHadler = new FirstCacheHadler();                CacheHandler secondCacheHadler = new SecondCacheHadler();                //设置下级处理者                firstCacheHadler.setNext(secondCacheHadler);                //获取处理级别                int cacheLevel = getCacheLevel(key, nextKey);                RedisResult result = new RedisResult(redisUtil, key, nextKey, joinPoint, cacheLevel, expireTime);                //客户端调用                return firstCacheHadler.HandleMessage(result);        }         private int getCacheLevel(String key, String nextKey) {                if (StringUtil.isNotEmpty(key) && StringUtil.isNotEmpty(nextKey)) {                        return 2;                } else {                        return 1;                }        }         private int getExpireTime(ExtCacheable annotation) {                return annotation.expireTime();        }         private String getRedisKey(Object[] args, String primalKey) {                // 获取#p0...集合                List keyList = getKeyParsList(primalKey);                for (String keyName : keyList) {                        int keyIndex = Integer.parseInt(keyName.toLowerCase().replace("#p", ""));                        Object parValue = args[keyIndex];                        primalKey = primalKey.replace(keyName, String.valueOf(parValue));                }                return primalKey.replace("+", "").replace("'", "");        }         // 获取key中#p0中的参数名称        private static List getKeyParsList(String key) {                List ListPar = new ArrayList();                if (key.indexOf("#") >= 0) {                        int plusIndex = key.substring(key.indexOf("#")).indexOf("+");                        int indexNext = 0;                        String parName = "";                        int indexPre = key.indexOf("#");                        if (plusIndex > 0) {                                indexNext = key.indexOf("#") + key.substring(key.indexOf("#")).indexOf("+");                                parName = key.substring(indexPre, indexNext);                        } else {                                parName = key.substring(indexPre);                        }                        ListPar.add(parName.trim());                        key = key.substring(indexNext + 1);                        if (key.indexOf("#") >= 0) {                                ListPar.addAll(getKeyParsList(key));                        }                }                return ListPar;        } }

CacheHandler:

package com.huajie.common.cache;/** * @author xiewenfeng 缓存处理接口 * 责任链模式 */public abstract class CacheHandler {        // 定义处理级别        protected final static int FirstCache_LEVEL_REQUEST = 1;        protected final static int SecondCache_LEVEL_REQUEST = 2;         // 能处理的级别        private int level = 0;        // 责任传递,下一个责任人是谁        private CacheHandler nextHandler;         // 每个类自己能处理那些请求        public CacheHandler(int level) {                this.level = level;        }         // 处理请求        public final Object HandleMessage(RedisResult redisResult) throws Throwable {                //如果women类型为当前处理的level                if(redisResult.getCacheLevel()==this.level){                        return this.response(redisResult);                }else{                         if(null!=this.nextHandler){                                 return this.nextHandler.HandleMessage(redisResult);                         }else{                                 //没有下级不处理                                 return null;                         }                }        }         public void setNext(CacheHandler handler) {                this.nextHandler = handler;        }         // 有请示的回应        protected abstract Object response(RedisResult redisResult) throws Throwable;}

FirstCacheHadler:一级缓存处理者

package com.huajie.common.cache; import org.aspectj.lang.ProceedingJoinPoint;import com.huajie.utils.RedisUtil; public class FirstCacheHadler extends CacheHandler{         public FirstCacheHadler() {                super(CacheHandler.FirstCache_LEVEL_REQUEST);        }         @Override        protected Object response(RedisResult redisResult) throws Throwable {                String key = redisResult.getKey();                RedisUtil redisUtil = redisResult.getRedisUtil();                boolean  hasKey = redisUtil.hasKey(key);                ProceedingJoinPoint joinPoint = redisResult.getJoinPoint();                int expireTime = redisResult.getExpireTime();                if (hasKey) {                        return redisUtil.get(key);                } else {                        Object res = joinPoint.proceed();                        redisUtil.set(key, res);                        redisUtil.expire(key, expireTime);                        return res;                }        } }

SecondCacheHadler:二级缓存处理者

package com.huajie.common.cache; import org.aspectj.lang.ProceedingJoinPoint;import com.huajie.utils.RedisUtil; public class SecondCacheHadler extends CacheHandler {         public SecondCacheHadler() {                super(CacheHandler.SecondCache_LEVEL_REQUEST);        }         @Override        protected Object response(RedisResult redisResult) throws Throwable {                String nextKey = redisResult.getNextKey();                String key = redisResult.getKey();                RedisUtil redisUtil = redisResult.getRedisUtil();                ProceedingJoinPoint joinPoint = redisResult.getJoinPoint();                int expireTime = redisResult.getExpireTime();                boolean hasKey = redisUtil.hasKey(key);                if (hasKey) {                        return redisUtil.get(key);                } else {                        boolean hasNextKey = redisUtil.hasKey(nextKey);                        if (hasNextKey) {                                return redisUtil.get(nextKey);                        } else {                                Object res = joinPoint.proceed();                                redisUtil.set(nextKey, res);                                redisUtil.expire(nextKey, expireTime);                                return res;                        }                }        }}

RedisResult:该业务场景对象,用于传递参数

package com.huajie.common.cache; import org.aspectj.lang.ProceedingJoinPoint;import com.huajie.utils.RedisUtil;import lombok.Data; @Datapublic class RedisResult implements IRedisResult {        private int cacheLevel;        private Object result;        private RedisUtil redisUtil;        private String key;        private String nextKey;        private int expireTime;        private ProceedingJoinPoint joinPoint;         @Override        public int getCacheLevel() {                return cacheLevel;        }         @Override        public Object getResult() {                return result;        }         public RedisResult(RedisUtil redisUtil, String key, String nextKey, ProceedingJoinPoint joinPoint, int cacheLevel,int expireTime) {                this.redisUtil = redisUtil;                this.key = key;                this.joinPoint = joinPoint;                this.cacheLevel = cacheLevel;                this.nextKey = nextKey;                this.expireTime = expireTime;        } }

使用方法如下:

@Override        @ExtCacheable(key = "middle+#p0+#p1+#p2", nextKey = "middle+#p0+#p2")        public List listMiddleManageInfo(String leadergroupId, String uuid, String yearDetailId) {                Map map = new HashMap();                map.put("leadergroupId", leadergroupId);                map.put("uuid", uuid);                map.put("yearDetailId", yearDetailId);                List middleManageDetailList = middleManageMapper.listMiddleManageInfo(map);                return middleManageDetailList;        }

上述内容就是java设计模式中的责任链模式是什么,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

处理 缓存 模式 方法 责任 参数 对象 人员 数据 查询 设计 注解 级别 设计模式 业务 多个 接口 数据库 原始 下级 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技园 高科技与互联网 北京禾田雨橡互联网科技 深圳卡尔迅互联网科技有限公司怎么样 新华互联网科技2019 港股科技和互联网 互联网还是高科技吗 晓花互联网科技有限公司网址 未来五年的互联网科技 民营互联网公司国防科技 华夏恒生互联网科技013171 互联网营销推广黑科技 上海互联网科技公司ppt 有人说阿里系是互联网科技企业 35岁以上互联网科技行业 陕西九四连强互联网科技有限公司 保山互联网科技靠谱吗 福仕德教育科技互联网 互联网的科技体现在哪里 互联网科技自媒体灵感 今日互联网科技 互联网科技产品 互联网新科技动漫ppt素材 烟台灵鸽互联网科技有限公司 深圳互联网科技的发展 浙南科技城互联网大厦招聘 下一代互联网重大应用科技园 工业互联网科技创业 山东大美朱楼互联网科技有限公司 云鲸互联网络科技有限公司
0