使用Spring特性优雅书写业务代码

在上面这个案例当中的重试策略就是重试5次,每次延时3秒。详细的使用文档看这里,它的主要配置参数有下面这样几个。其中exclude、include、maxAttempts、value几个属性很容易理解,比较看不懂的是backoff属性,它也是个注解,包含delay、maxDelay、multiplier、random四个属性。

  • delay: 如果不设置的话默认是1秒

  • maxDelay: 最大重试等待时间

  • multiplier: 用于计算下一个延迟时间的乘数(大于0生效)

  • random: 随机重试等待时间(一般不用)

使用Spring特性优雅书写业务代码

Spring Retry的优点很明显,第一,属于Spring大生态,使用起来不会太生硬;第二,只需要在需要重试的方法上加上注解并配置重试策略属性就好,不需要太多侵入代码。

但同时也存在两个主要不足,第一,由于Spring Retry用到了Aspect增强,所以就会有使用Aspect不可避免的坑——方法内部调用,如果被 @Retryable 注解的方法的调用方和被调用方处于同一个类中,那么重试将会失效;第二,Spring的重试机制只支持对异常进行捕获,而无法对返回值进行校验判断重试。如果想要更灵活的重试策略可以考虑使用Guava Retry,也是一个不错的选择。

优雅使用Spring特性完成业务策略模式

====================

策略模式相信大家都应该比较熟悉,它定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。

其适用的场景是这样的:一个大功能,它有许多不同类型的实现(策略类),具体根据客户端来决定采用哪一个策略类。比如下单优惠策略、物流对接策略等,应用场景还是非常多的。

使用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 属性执行定制初始化逻辑。

使用Spring特性优雅书写业务代码

可以很明显地看出,如果以后还有一些其他的业务需要制定相应的鉴权逻辑,我们只需要编写对应的策略类就好了,无需再破坏当前 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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

分享

这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!

薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了

Spring Cloud实战

薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了

Spring Boot实战

薪酬缩水,“裸辞”奋战25天三面美团,交叉面却被吊打,我太难了

面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

分享

这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!

[外链图片转存中…(img-O69PvORR-1712761139726)]

Spring Cloud实战

[外链图片转存中…(img-qa8HOewj-1712761139726)]

Spring Boot实战

[外链图片转存中…(img-bqqZ7MO3-1712761139727)]

面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Spring实现用户登录的JavaEE代码可以分为以下几个步骤: 1. 创建用户实体类: 首先,需要创建一个用户实体类,用于存储用户的信息,例如用户名和密码等。 2. 创建用户数据访问层接口和实现类: 创建一个用户数据访问层接口,定义用户相关的数据库操作方法,例如查询用户信息、添加用户等。然后,创建一个实现该接口的类,实现具体的数据库操作逻辑。 3. 创建用户服务层接口和实现类: 创建一个用户服务层接口,定义用户相关的业务逻辑方法,例如用户登录验证、注册用户等。然后,创建一个实现该接口的类,实现具体的业务逻辑。 4. 创建控制器: 创建一个控制器类,用于接收用户请求并调用相应的服务层方法进行处理。在控制器中,可以使用Spring的注解来标识该类为控制器,并通过注解注入服务层对象。 5. 配置Spring配置文件: 在Spring配置文件中,配置数据源、事务管理器、扫描包路径等相关信息。同时,配置控制器和服务层对象的注入。 6. 创建登录页面: 创建一个登录页面,用于用户输入用户名和密码,并提交登录请求。 7. 编写前端页面代码: 在前端页面中,使用表单提交用户输入的用户名和密码,并将其发送到后台进行验证。 8. 编写登录请求处理代码: 在控制器中,编写处理登录请求的代码。通过调用服务层的方法,对用户输入的用户名和密码进行验证,并根据验证结果返回相应的响应。 9. 部署和运行: 将项目部署到服务器上,并启动服务器,然后通过浏览器访问登录页面,输入用户名和密码进行登录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值