目录
前言
一、结构中包含的角色
二、拦截器使用
1.拦截器角色
a.自定义拦截器UserValidateInterceptor,UserUpdateInterceptor,UserEditNameInterceptor
b.拦截器配置者UserInterceptorChainConfigure,任意组装拦截器顺序
c.拦截器管理者UserInterceptorChainManager
2.运行结果展示
a.使用代码
三、拦截器调用解说
1.项目启动,初始化bean
2.方法执行
四、代码下载
总结
拦截过滤器模式,简称拦截器模式,是责任链模式的一种衍生模式。用于对业务程序做一些预处理/后处理
/*** 校验用户* @author liangxi.zeng*/
@Component
public class UserValidateInterceptor implements Interceptor {/*** 拦截方法** @param user*/@Overridepublic void interceptor(User user) {if(user.getAge() != 10) {throw new CommonException("年龄不对");}System.out.println("校验用户"+user);}
}
@Component
public class UserInterceptorChainConfigureimplements InterceptorChainConfigure> {/*** 拦截器链配置** @param interceptorChainBuilder 拦截器链构造器*/@Overridepublic void configure(InterceptorChainBuilder interceptorChainBuilder) {interceptorChainBuilder.pre().addInterceptor(UserValidateInterceptor.class).post().addInterceptor(UserUpdateInterceptor.class).addInterceptor(UserEditNameInterceptor.class);}
}
/*** @author liangxi.zeng* 拦截器链管理类*/
@Component
public class UserInterceptorChainManager
extends AbstractInterceptorChainManager {public UserInterceptorChainManager(List> interceptorList,List>> configureList) {super(interceptorList, configureList);}
}
/*** @author liangxi.zeng*/
@RestController
@RequestMapping("/demo")
public class DemoController {@Autowiredprivate UserInterceptorChainManager userInterceptorChainManager;@Autowiredprivate UserService userService;@RequestMapping("/user")public String user() {User user = new User();user.setId("111");user.setName("liangxi");user.setAge(10);userInterceptorChainManager.doInterceptor(user,(u) -> {// 内部创建用户userService.save(user);});return "success";}}
a.初始化责任链管理者UserInterceptorChainManager,调用父类AbstractInterceptorChainManager方法initInterceptorChain,通过责任链建造者初始化责任链
public AbstractInterceptorChainManager(List> interceptorList,List>> configureList) {interceptorChain = initInterceptorChain(interceptorList, configureList);LOGGER.info("Register {} InterceptorChain, names are [{}]",interceptorList);}private InterceptorChain initInterceptorChain(List> interceptorList,List>> configureList) {if (CollectionUtils.isEmpty(interceptorList)) {throw new IllegalArgumentException("Interceptors is empty.");}if (CollectionUtils.isEmpty(configureList)) {throw new IllegalArgumentException("Interceptor configurers is empty.");}InterceptorChainBuilder builder = new InterceptorChainBuilder<>(interceptorList);configureList.sort(AnnotationAwareOrderComparator.INSTANCE);configureList.forEach(configurer -> {configurer.configure(builder);});return builder.performBuild();}
b.责任链建造者,完成对业务方法前后逻辑的织入
public InterceptorChain performBuild() {List> preInterceptors = filterInterceptor(preInterceptorList);List> postInterceptors = filterInterceptor(postInterceptorList);if (preInterceptors.isEmpty() && postInterceptors.isEmpty()) {throw new IllegalStateException("Registered Pre-Interceptors and Post-Interceptors is empty.");}Consumer preConsumer = (T t) -> {};Consumer postConsumer = (T t) -> {};if (!preInterceptors.isEmpty()) {preConsumer = (T obj) -> {for (Interceptor item : preInterceptors) {item.interceptor(obj);}};}if (!postInterceptors.isEmpty()) {postConsumer = (T obj) -> {for (Interceptor item : postInterceptors) {item.interceptor(obj);}};}return new InterceptorChain(preConsumer,postConsumer);}
a.从userInterceptorChainManager.doInterceptor 到 interceptorChain.doExecute(target, operation);下面代码,完成代码逻辑
/*** 拦截器调用入口,将核心操作封装成 Consumer 对象传入。** @param target The target to handle.* @param operation The core operation to intercept.*/public final void doExecute(T target, Operation operation) {preConsumer.accept(target);if (operation != null) {operation.execute(target);}postConsumer.accept(target);}
设计模式可运行代码https://gitee.com/zenglx/design-pattern.git
前后端请求,可以用现成的filter和spring的Interceptor解决,业务自己的拦截器链模式,可以解决繁琐业务重复代码的问题