免费asp网站模板,网站建设及推广衬胶蝶阀,wordpress视频自适应代码,dede 购物网站文章目录一、责任链1. 责任链基本概念2. 定义3. 关键要点4. 责任链模式优缺点5. 责任链模式类结构图6. 网关权限控制责任链模式二、构建企业级风控系统2.1. 定义公共抽象任务2.2. (失信名单)校验处理类2.3. (信用卡)逾期处理类2.4. (蚂蚁信用积分)处理类2.5. 责任链工厂(第一种…
文章目录一、责任链1. 责任链基本概念2. 定义3. 关键要点4. 责任链模式优缺点5. 责任链模式类结构图6. 网关权限控制责任链模式二、构建企业级风控系统2.1. 定义公共抽象任务2.2. (失信名单)校验处理类2.3. (信用卡)逾期处理类2.4. (蚂蚁信用积分)处理类2.5. 责任链工厂(第一种)三、模式重构升级3.1. mysql表结构3.2. 任务实体3.3. 责任链接口3.4. Spring上下文工具类3.5. 责任链处理类3.6. 测试入口3.7. 扫描配置3.8. yml配置3.9. maven3.10. 开源项目一、责任链
1. 责任链基本概念
客户端发出一个请求链上的对象都有机会来处理这一请求而客户端不需要知道谁是具体的处理对象。这样就实现了请求者和接受者之间的解耦并且在客户端可以实现动态的组合职责链。使编程更有灵活性。
2. 定义
使多个对象都有机会处理请求从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链并沿着这条链传递该请求直到有对象处理它为止。其过程实际上是一个递归调用。
3. 关键要点
1、有多个对象共同对一个任务进行处理。 2、这些对象使用链式存储结构形成一个链每个对象知道自己的下一个对象。 3、一个对象对任务进行处理可以添加一些操作后将对象传递个下一个任务。也可以在此对象上结束任务的处理并结束任务。 4、客户端负责组装链式结构但是客户端不需要关心最终是谁来处理了任务。 多个对象指的是什么意思
4. 责任链模式优缺点
优点 职责链模式的最主要功能就是动态组合请求者和接受者解耦。 请求者和接受者松散耦合请求者不需要知道接受者也不需要知道如何处理。每个职责对象只负责自己的职责范围其他的交给后继者。各个组件间完全解耦。 动态组合职责职责链模式会把功能分散到单独的职责对象中然后在使用时动态的组合形成链从而可以灵活的分配职责对象也可以灵活的添加改变对象职责。
缺点 产生很多细粒度的对象因为功能处理都分散到了单独的职责对象中每个对象功能单一要把整个流程处理完需要很多的职责对象会产生大量的细粒度职责对象。 不一定能处理每个职责对象都只负责自己的部分这样就可以出现某个请求即使把整个链走完都没有职责对象处理它。这就需要提供默认处理并且注意构造链的有效性。
5. 责任链模式类结构图
1.抽象处理者(Handler)角色定义出一个处理请求的接口。如果需要接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用抽象方法handleRequest()规范了子类处理请求的操作。 2.具体处理者(ConcreteHandler)角色具体处理者接到请求后可以选择将请求处理掉或者将请求传给下家。由于具体处理者持有对下家的引用因此如果需要具体处理者可以访问下家 责任链模式应用场景
多条件流程判断 权限控制ERP系统 流程审批 总经理、人事经理、项目经理Java过滤器的底层实现Filter风控系统 失信名单→信用卡是否逾期→蚂蚁信用积分650 比如在Java过滤器中客户端发送请求到服务器端过滤会经过参数过滤、session过滤、表单过滤、隐藏过滤、检测请求头过滤 6. 网关权限控制责任链模式
在网关作为微服务程序的入口拦截客户端所有的请求实现权限控制 比如先判断Api接口限流、黑名单、用户会话、参数过滤。 Api接口限流→黑名单拦截→用户会话→参数过滤
二、构建企业级风控系统
2.1. 定义公共抽象任务
package com.gblfy.mapper;/*** 公共抽象任务** author gblfy* date 2022-03-14*/
public abstract class GatewayHandler {/*** 处理业务逻辑*/public abstract void doService();protected GatewayHandler nextGatewayHandler;public GatewayHandler() {}public GatewayHandler(GatewayHandler nextGatewayHandler) {this.nextGatewayHandler nextGatewayHandler;}//责任链工厂时用到此构造方法public void setNextGatewayHandler(GatewayHandler nextGatewayHandler) {this.nextGatewayHandler nextGatewayHandler;}
}
2.2. (失信名单)校验处理类
package com.gblfy.service;import com.gblfy.mapper.GatewayHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;/*** (失信名单)校验** author gblfy* date 2022-03-14*/
Slf4j
Service
public class DishonestListHandler extends GatewayHandler {public DishonestListHandler() {}public DishonestListHandler(GatewayHandler nextGatewayHandler) {super(nextGatewayHandler);}Overridepublic void doService() {log.info(---------------------(失信名单)校验处理逻辑---------------------);nextGatewayHandler.doService();}
}
2.3. (信用卡)逾期处理类
package com.gblfy.service;import com.gblfy.mapper.GatewayHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;/*** (信用卡)逾期** author gblfy* date 2022-03-14*/
Slf4j
Service
public class CreditCardOverdueHandler extends GatewayHandler {public CreditCardOverdueHandler() {}Overridepublic void doService() {log.info(---------------------(信用卡)逾期处理逻辑---------------------);nextGatewayHandler.doService();}public CreditCardOverdueHandler(GatewayHandler nextGatewayHandler) {super(nextGatewayHandler);}
}
2.4. (蚂蚁信用积分)处理类
package com.gblfy.service;import com.gblfy.mapper.GatewayHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;/*** (蚂蚁信用积分)** author gblfy* date 2022-03-14*/
Slf4j
Service
public class CreditPointsHandler extends GatewayHandler {public CreditPointsHandler() {}Overridepublic void doService() {log.info(---------------------(蚂蚁信用积分)处理逻辑---700分------------------);}public CreditPointsHandler(GatewayHandler nextGatewayHandler) {super(nextGatewayHandler);}
}
2.5. 责任链工厂(第一种)
package com.gblfy.factory;import com.gblfy.service.CreditCardOverdueHandler;
import com.gblfy.service.DishonestListHandler;
import com.gblfy.service.CreditPointsHandler;
import org.springframework.stereotype.Component;/*** 责任链工厂(第一种)** author gblfy* date 2022-03-14*/
Component
public class FactoryHandler {public DishonestListHandler getCurrentLimitHandler() {DishonestListHandler dishonestListHandler new DishonestListHandler();CreditCardOverdueHandler creditCardOverdueHandler new CreditCardOverdueHandler();//失信名单指向-用卡是否逾期校验dishonestListHandler.setNextGatewayHandler(creditCardOverdueHandler);//信用卡是否逾期校验指向-蚂蚁信用积分是否大于700分creditCardOverdueHandler.setNextGatewayHandler(new CreditPointsHandler());return dishonestListHandler;}public static void main(String[] args) {new FactoryHandler().getCurrentLimitHandler().doService();}
}
三、模式重构升级
3.1. mysql表结构
drop database IF EXISTS design_pattern;
create database design_pattern;
use design_pattern;SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS 0;-- ----------------------------
-- Table structure for gblfy_strategy
-- ----------------------------
DROP TABLE IF EXISTS gateway_handler;
CREATE TABLE gateway_handler (id int NOT NULL AUTO_INCREMENT COMMENT 主键ID,handler_name varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 节点名称,handler_id varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 节点主键id,prev_handler_id varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 上一个节点,next_handler_id varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 下一个节点,PRIMARY KEY (id) USING BTREE
) ENGINE InnoDB AUTO_INCREMENT 19 CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT 权限表 ROW_FORMAT DYNAMIC;-- ----------------------------
-- Records of gateway_handler
-- ----------------------------
INSERT INTO gateway_handler VALUES (16, 失信名单校验, dishonestListHandler, NULL, creditCardOverdueHandler);
INSERT INTO gateway_handler VALUES (17, 信用卡是否逾期, creditCardOverdueHandler, dishonestListHandler, creditPointsHandler);
INSERT INTO gateway_handler VALUES (18, 蚂蚁积分是否大于700分, creditPointsHandler, creditCardOverdueHandler, NULL);3.2. 任务实体
package com.gblfy.entity;import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;Data
TableName(gateway_handler)
public class GatewayHandlerEntity {// 策略配置主键TableId(value id, type IdType.ASSIGN_ID)private Long id;//节点名称Api接口限流、黑名单拦截、token验证TableField(handler_name)private String handlerName;//节点IDTableField(handler_id)private String handlerId;//上一个节点TableField(prev_handler_id)private String prevHandlerId;//下一个节点TableField(next_handler_id)private String nextHandlerId;
}
3.3. 责任链接口
package com.gblfy.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gblfy.entity.GatewayHandlerEntity;/*** 责任链接口** author gblfy* date 2022-03-13*/
public interface GatewayHandlerMapper extends BaseMapperGatewayHandlerEntity {
}
3.4. Spring上下文工具类
package com.gblfy.utils;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;/*** 获取Spring上下文工具类** author gblfy* date 2022-03-13*/
Component
public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtils.applicationContext applicationContext;}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name) {return getApplicationContext().getBean(name);}//通过class获取Bean.public static T T getBean(ClassT clazz) {return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static T T getBean(String name, ClassT clazz) {return getApplicationContext().getBean(name, clazz);}}
3.5. 责任链处理类
package com.gblfy.factory;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gblfy.entity.GatewayHandlerEntity;
import com.gblfy.mapper.GatewayHandler;
import com.gblfy.mapper.GatewayHandlerMapper;
import com.gblfy.utils.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** 责任链处理类(数据库方案)** author gblfy* date 2022-03-14*/
Slf4j
Component
public class DbHandle {Autowiredprivate GatewayHandlerMapper gatewayHandlerMapper;private GatewayHandler firstGatewayHandler;//当数据库审批节点发生变化时需要将firstGatewayHandler设置为nullpublic GatewayHandler getFirstGatewayHandler() {if (firstGatewayHandler ! null) {return firstGatewayHandler;}// 1.查询头节点handle beanid 查询prev_handler_id为空的情况下标明为头节点GatewayHandlerEntity gatewayHandlerEntity gatewayHandlerMapper.selectOne(new QueryWrapperGatewayHandlerEntity().lambda().isNull(GatewayHandlerEntity::getPrevHandlerId));if (gatewayHandlerEntity null) {log.error(很抱歉您没有配置头节点);return null;}// 2.获取头节点的handleidString firstHandlerId gatewayHandlerEntity.getHandlerId();if (StringUtils.isEmpty(firstHandlerId)) {log.error(很抱歉您没有配置头节点);return null;}// 3.从容器中获取HandlerId对应的对象firstGatewayHandler SpringContextUtils.getBean(firstHandlerId, GatewayHandler.class);if (firstGatewayHandler null) {log.error(您的代码中没有配置{}, firstHandlerId ,的对象);return null;}// 4.能够成功获取限流处理器获取下一个处理器beanidString nextHandlerId gatewayHandlerEntity.getNextHandlerId();// 5.定义一个中间变量解决最后一个对象覆盖第一个对象的问题-记录当前循环的对象GatewayHandler tempGatewayHandler firstGatewayHandler;// 6.当下一个节点不为空时开始递归获取while (StringUtils.isNotBlank(nextHandlerId)) {// 7.从spring容器中获取下一个节点对象GatewayHandler nextgatewayHandler SpringContextUtils.getBean(nextHandlerId, GatewayHandler.class);if (nextgatewayHandler null) {break;}GatewayHandlerEntity nextGatewayHandlerEntity gatewayHandlerMapper.selectOne(new QueryWrapperGatewayHandlerEntity().lambda().eq(GatewayHandlerEntity::getHandlerId, nextHandlerId));if (nextGatewayHandlerEntity null) {break;}nextHandlerId nextGatewayHandlerEntity.getNextHandlerId();// 8.这是责任链关键代码tempGatewayHandler.setNextGatewayHandler(nextgatewayHandler);tempGatewayHandler nextgatewayHandler;}// 9.为了避免每次都查询db这里第一次查询之后可以缓存到全局变量中下次查询时直接返回this.firstGatewayHandler firstGatewayHandler;return firstGatewayHandler;}
}
3.6. 测试入口
package com.gblfy.controller;import com.gblfy.factory.DbHandle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;RestController
public class HandleController {Autowiredprivate DbHandle dbHandle;GetMapping(/getHandle)public void getHandle() {dbHandle.getFirstGatewayHandler().doService();}
}
3.7. 扫描配置
package com.gblfy.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;Configuration
MapperScan(com.gblfy.mapper)
public class MybatisPlusConfig {}
3.8. yml配置
server:port: 8080
spring:datasource:username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/design_pattern?useUnicodetruecharacterEncodingUTF-8
logging:level:com.gblfy.mapper: DEBUG
mybatis-plus:configuration:log-impl:mapper-locations: classpath:mappers/*.xml
3.9. maven dependencies!--字符串工具类--dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.12.0/version/dependency!--数据json处理--dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.79/version/dependency!--SpringMVC--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!--mybatis-plus 持久化--dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion3.5.1/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependencies
3.10. 开源项目
https://gitee.com/gblfy/design-pattern/tree/duty-chain