In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article shows you what the chain of responsibility pattern in the java design pattern is. The content is concise and easy to understand. It will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.
One: mode description
Schema definition: multiple objects have the opportunity to process the request, thus avoiding the coupling relationship between the sender and receiver of the request. Join these objects into a chain and pass the request along the chain until an object processes it.
The focus of the chain of responsibility pattern is on the "chain", where a similar request is processed by a chain to determine who will process the request in the chain and return the corresponding results (taken from the Zen of Design patterns).
The Client object calls the method of a handler (class), and there may be multiple handlers (implementing class), but the object only needs to call the first handler (class), and the pattern automatically assigns who will handle the request; these multiple handlers inherit the same parent class (that is, on a chain).
The general class diagram is as follows:
Client sends a request to Handler,Handler to automatically allocate the request to the implementation class ConcreteHandler of the subclass.
Second: project actual combat
Support expiration time settings in articles > handwritten redis@Cacheable comments
< 的基础之上做修改,原版为redis缓存注解实现, 原版实现功能: 将数据存放到redis中 设置过期时间 原业务逻辑查询人员列表listleader()接口,数据存放redis中,减少数据库负载。 由于业务发展,需要进一步优化查询接口;目前每个人都会操作redis中存放的人员列表,导致该列表会实时发生变动(比如 每个人员对应的分数),每个人都有自己的缓存人员列表而不是统一的人员列表;原列表已经无法满足现需求,每个人第一次登 录都会查询数据库,将自己的列表存放在redis中。 解决方法:设置两级缓存,第一级为该用户(uuid)唯一缓存,key值设置为参数1+uuid+参数2;第二级为第一次登录查询返 回redis中的原始leader列表,key值设置为参数1+参数2。如果当前用户leader列表(一级缓存)为空,则查询原始leader列表 (二级缓存),在操作分数的时候修改二级缓存(初始人员列表)来产生一级缓存,存放进redis,减少了数据库的直接访问。 项目中责任链相关设计类图如下:Description: abstract class CacheHandler defines the request processing method handleMessage;, defines the choreography method setNext of a chain, sets the next handler, and defines two methods that a specific requester must implement: define the level of getHandlerLevel that he can handle and the specific processing task response.
FirstCacheHadler is the first-level cache processor and SecondCacheHadler is the second-level cache processor. The method of cache handling is called through the CacheableAspect class.
Three: source code
CacheableAspect:client call
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 cache processing is not suitable for internal method calls (this.) Or 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 {/ / get the currently visited class Class className = joinPoint.getTarget (). GetClass () / / the name of the accessed method String methodName = joinPoint.getSignature () .getName (); / / the type of the method's parameters Class [] argClass = ((MethodSignature) joinPoint.getSignature ()) .getParameterTypes (); Object [] args = joinPoint.getArgs (); String key = "" String nextKey = ""; int expireTime = 1800; try {/ / access method object Method method = className.getMethod (methodName, argClass); method.setAccessible (true) / / determine whether there is @ ExtCacheable annotation 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 cache comment parameter exception", e) } / / chain of responsibility mode CacheHandler firstCacheHadler = new FirstCacheHadler (); CacheHandler secondCacheHadler = new SecondCacheHadler (); / / set lower-level processor firstCacheHadler.setNext (secondCacheHadler); / / get processing level int cacheLevel = getCacheLevel (key, nextKey) RedisResult result = new RedisResult (redisUtil, key, nextKey, joinPoint, cacheLevel, expireTime); / / client calls 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) {/ / get # p0... Set 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 ("'",");} / / get the parameter name private static List getKeyParsList (String key) {List ListPar = new ArrayList () in # p0 in key 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 cache processing interface * chain of responsibility mode * / public abstract class CacheHandler {/ / define processing levels protected final static int FirstCache_LEVEL_REQUEST = 1; protected final static int SecondCache_LEVEL_REQUEST = 2; / / levels that can be handled private int level = 0 / / responsibility passing, who is the next responsible person private CacheHandler nextHandler; / / each class can handle those requests by itself public CacheHandler (int level) {this.level = level } / / process the request public final Object HandleMessage (RedisResult redisResult) throws Throwable {/ / if the women type is the currently processed level if (redisResult.getCacheLevel () = = this.level) {return this.response (redisResult) } else {if (nullinherthis.nextHandler) {return this.nextHandler.HandleMessage (redisResult);} else {/ / No subordinate does not handle return null } public void setNext (CacheHandler handler) {this.nextHandler = handler;} / / response to request protected abstract Object response (RedisResult redisResult) throws Throwable;}
FirstCacheHadler: first-level cache processor
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: second-tier cache processor
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: this business scenario object, which is used to pass parameters
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;}}
The method of use is as follows:
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;} what is the chain of responsibility pattern in the java design pattern? have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.