在上面这个案例当中的重试策略就是重试5次,每次延时3秒。详细的使用文档看这里,它的主要配置参数有下面这样几个。其中exclude、include、maxAttempts、value几个属性很容易理解,比较看不懂的是backoff属性,它也是个注解,包含delay、maxDelay、multiplier、random四个属性。
-
delay: 如果不设置的话默认是1秒
-
maxDelay: 最大重试等待时间
-
multiplier: 用于计算下一个延迟时间的乘数(大于0生效)
-
random: 随机重试等待时间(一般不用)
Spring Retry的优点很明显,第一,属于Spring大生态,使用起来不会太生硬;第二,只需要在需要重试的方法上加上注解并配置重试策略属性就好,不需要太多侵入代码。
但同时也存在两个主要不足,第一,由于Spring Retry用到了Aspect增强,所以就会有使用Aspect不可避免的坑——方法内部调用,如果被 @Retryable 注解的方法的调用方和被调用方处于同一个类中,那么重试将会失效;第二,Spring的重试机制只支持对异常进行捕获,而无法对返回值进行校验判断重试。如果想要更灵活的重试策略可以考虑使用Guava Retry,也是一个不错的选择。
优雅使用Spring特性完成业务策略模式
====================
策略模式相信大家都应该比较熟悉,它定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。
其适用的场景是这样的:一个大功能,它有许多不同类型的实现(策略类),具体根据客户端来决定采用哪一个策略类。比如下单优惠策略、物流对接策略等,应用场景还是非常多的。
举一个简单的例子,业务背景是这样的:平台需要根据不同的业务进行鉴权,每个业务的鉴权逻辑不一样,都有自己的一套独立的判断逻辑,因此需要根据传入的 bizType 进行鉴权操作,首先我们定义一个权限校验处理器接口如下。
/**
- 业务权限校验处理器
*/
publicinterface PermissionCheckHandler {
/**
- 判断是否是自己能够处理的权限校验类型
*/
boolean isMatched(BizType bizType);
/**
- 权限校验逻辑
*/
PermissionCheckResultDTO permissionCheck(Long userId, String bizCode);
}
业务1的鉴权逻辑我们假设是这样的:
/**
- 冷启动权限校验处理器
*/
@Component
publicclass ColdStartPermissionCheckHandlerImpl implements PermissionCheckHandler {
@Override
public boolean isMatched(BizType bizType) {
return BizType.COLD_START.equals(bizType);
}
@Override
public PermissionCheckResultDTO permissionCheck(Long userId, String bizCode) {
//业务特有鉴权逻辑
}
}
业务2的鉴权逻辑我们假设是这样的:
/**
- 趋势业务权限校验处理器
*/
@Component
publicclass TrendPermissionCheckHandlerImpl implements PermissionCheckHandler {
@Override
public boolean isMatched(BizType bizType) {
return BizType.TREND.equals(bizType);
}
@Override
public PermissionCheckResultDTO permissionCheck(Long userId, String bizCode){
//业务特有鉴权逻辑
}
}
可能还有很多其他的业务鉴权逻辑,这里就不一一列举了,实现逻辑像上面这样组织就好了。接着就到了关键的地方了,上面我们定义了这么多策略,应该怎么优雅地组织起来呢,这就需要用到Spring提供的一些扩展特性了,Spring主要为我们提供了三类扩展点,分别对应不同Bean生命周期阶段:
-
Aware接口
-
BeanPostProcessor
-
InitializingBean 和 init-method
我们这里用到的主要是 Aware 接口和 InitializingBean 两个扩展点,其主要用法如下代码所示,关键点就在于实现 ApplicationContextAware 接口的 setApplicationContext 方法和 InitializingBean 接口的 afterPropertiesSet 方法。
实现 ApplicationContextAware 接口的目的就是要拿到 Spring 容器的资源,从而方便的使用它提供的 getBeansOfType 方法(该方法返回的是 map 类型,key 对应 beanName, value 对应 bean);而实现 InitializingBean 接口的目的则是方便为 Service 类的 handlers 属性执行定制初始化逻辑。
可以很明显地看出,如果以后还有一些其他的业务需要制定相应的鉴权逻辑,我们只需要编写对应的策略类就好了,无需再破坏当前 Service 类的逻辑,很好的保证了开闭原则。
/**
- 权限校验服务类
*/
@Slf4j
@Service
publicclass PermissionServiceImpl
implements PermissionService, ApplicationContextAware, InitializingBean {
private ApplicationContext applicationContext;
//注:这里可以使用Map,偷个懒
private List handlers = new ArrayList<>();
@Override
public PermissionCheckResultDTO permissionCheck(ArtemisSellerBizType artemisSellerBizType, Long userId,
String bizCode) {
//省略一些前置逻辑
PermissionCheckHandler handler = getHandler(artemisSellerBizType);
return handler.permissionCheck(userId, bizCode);
}
private PermissionCheckHandler getHandler(ArtemisSellerBizType artemisSellerBizType) {
for (PermissionCheckHandler handler : handlers) {
if (handler.isMatched(artemisSellerBizType)) {
return handler;
}
}
returnnull;
}
@Override
public void afterPropertiesSet() throws Exception {
for (PermissionCheckHandler handler : applicationContext.getBeansOfType(PermissionCheckHandler.class)
.values()) {
handlers.add(handler);
log.warn(“load permission check handler [{}]”, handler.getClass().getName());
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/a2702e61abc05523a48560bd86d51c46.jpeg)
分享
这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!
Spring Cloud实战
Spring Boot实战
面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
分享
这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!
[外链图片转存中…(img-O69PvORR-1712761139726)]
Spring Cloud实战
[外链图片转存中…(img-qa8HOewj-1712761139726)]
Spring Boot实战
[外链图片转存中…(img-bqqZ7MO3-1712761139727)]
面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!