分享几个 SpringBoot 实用的小技巧(上)

简介: 这次分享一些 SpringBoot 使用中的一些小技巧。

屏蔽外部依赖


第一个是屏蔽外部依赖,什么意思呢?


比如大家日常开发时候有没有这样的烦恼:


项目是基于 SpringCloud 或者是 dubbo 这样的分布式服务,你需要依赖许多基础服务。


比如说某个订单号的生成、获取用户信息等。


由于服务拆分,这些功能都是在其他应用中以接口的形式提供,单测还好我还可以利用 Mock 把它屏蔽掉。


但如果自己想把应用启动起来同时把自己相关的代码跑一遍呢?


通常有几种做法:


  • 本地把所有的服务都启动起来。


  • 把注册中心换为开发环境,依赖开发环境的服务。


  • 直接把代码推送到开发环境自测。


看起来三种都可以,以前我也是这么干的。但还是有几个小问题:


  • 本地启动有可能服务很多,全部起来电脑能不能撑住还两说,万一服务有问题就进行不下去了。


  • 依赖开发环境的前提是网络打通,还有一个问题就是开发环境代码很不稳定很大可能会影响你的测试。


  • 推送到开发环境应该是比较靠谱的方案,但如果想调试只有日志大法,没有本地 debug 的效率高效。


那如何解决问题呢?既可以在本地调试也不用启动其他服务。


其实也可以利用单测的做法,把其他外部依赖 Mock 掉就行了。


大致的流程分为以下几步:


  • SpringBoot 启动之后在 Spring 中找出你需要屏蔽的那个 APIbean(通常情况下这个接口都是交给 Spring 管理的)。


  • 手动从 bean 容器中删除该 bean


  • 重新创建一个该 API 的对象,只不过是通过 Mock 出来的。


  • 再手动注册进 bean 容器中。


以下面这段代码为例:


@Override
    public BaseResponse<OrderNoResVO> getUserByHystrix(@RequestBody UserReqVO userReqVO) {
        OrderNoReqVO vo = new OrderNoReqVO();
        vo.setAppId(123L);
        vo.setReqNo(userReqVO.getReqNo());
        BaseResponse<OrderNoResVO> orderNo = orderServiceClient.getOrderNo(vo);
        return orderNo;
    }


这是一个 SpringCloud 应用。


它依赖于 orderServiceClient 获取一个订单号。


其中的 orderServiceClient 就是一个外部 API,也是被 Spring 所管理。


替换原有的 Bean


下一步就是替换原有的 Bean。


@Component
public class OrderMockServiceConfig implements CommandLineRunner {
    private final static Logger logger = LoggerFactory.getLogger(OrderMockServiceConfig.class);
    @Autowired
    private ApplicationContext applicationContext;
    @Value("${excute.env}")
    private String env;
    @Override
    public void run(String... strings) throws Exception {
        // 非本地环境不做处理
        if ("dev".equals(env) || "test".equals(env) || "pro".equals(env)) {
            return;
        }
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        OrderServiceClient orderServiceClient = defaultListableBeanFactory.getBean(OrderServiceClient.class);
        logger.info("======orderServiceClient {}=====", orderServiceClient.getClass());
        defaultListableBeanFactory.removeBeanDefinition(OrderServiceClient.class.getCanonicalName());
        OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
                invocationOnMock -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));
        defaultListableBeanFactory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi);
        logger.info("======mockOrderApi {}=====", mockOrderApi.getClass());
    }
}


其中实现了 CommandLineRunner 接口,可以在 Spring 容器初始化完成之后调用 run() 方法。


代码非常简单,简单来说首先判断下是什么环境,毕竟除开本地环境其余的都是需要真正调用远程服务的。


之后就是获取 bean 然后手动删除掉。


关键的一步:


OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
                invocationOnMock -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));
defaultListableBeanFactory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi)


相关文章
|
5月前
|
Java
springboot提高编辑Controller和Service层速度和规范小技巧
springboot提高编辑Controller和Service层速度和规范小技巧
|
NoSQL Java 数据库
【SpringBoot2 从0开始】开发小技巧 - lombok、devtools、Spring Initailizr
【SpringBoot2 从0开始】开发小技巧 - lombok、devtools、Spring Initailizr
【SpringBoot2 从0开始】开发小技巧 - lombok、devtools、Spring Initailizr
|
存储 Java 容器
【SpringBoot 2】(七)请求处理——映射 常用注解 方法参数的小技巧(二)
【SpringBoot 2】(七)请求处理——映射 常用注解 方法参数的小技巧(二)
143 0
【SpringBoot 2】(七)请求处理——映射 常用注解 方法参数的小技巧(二)
|
前端开发 Java 网络架构
【SpringBoot 2】(七)请求处理——映射 常用注解 方法参数的小技巧(一)
【SpringBoot 2】(七)请求处理——映射 常用注解 方法参数的小技巧(一)
301 0
【SpringBoot 2】(七)请求处理——映射 常用注解 方法参数的小技巧(一)
|
Java Spring
【SpringBoot 2】(五)自动配置简析源码 开发中小技巧(二)
【SpringBoot 2】(五)自动配置简析源码 开发中小技巧(二)
【SpringBoot 2】(五)自动配置简析源码 开发中小技巧(二)
|
Java 容器
【SpringBoot 2】(五)自动配置简析源码 开发中小技巧(一)
【SpringBoot 2】(五)自动配置简析源码 开发中小技巧(一)
110 0
【SpringBoot 2】(五)自动配置简析源码 开发中小技巧(一)
|
Java 微服务 Spring
尤娜故事-迷雾-springboot扮酷小技巧
尤娜故事-迷雾-springboot扮酷小技巧
尤娜故事-迷雾-springboot扮酷小技巧
|
Java API 数据库
分享几个 SpringBoot 实用的小技巧(下)
这次分享一些 SpringBoot 使用中的一些小技巧。
|
Java 数据库 Spring
springboot(十三):springboot小技巧
一些springboot小技巧、小知识点 初始化数据 我们在做测试的时候经常需要初始化导入一些数据,如何来处理呢?会有两种选择,一种是使用Jpa,另外一种是Spring JDBC。两种方式各有区别下面来详细介绍。
14333 0
|
监控 安全 Java
SpringBoot实用小技巧之动态设置SpringBoot日志级别
  有时线上问题我们用打日志的方式来观察错误或埋点参数,但由于这些日志如果都打出来会占用大量存储空间而且覆盖了一些有效信息,所以线上级别一般设置INFO,调试级别用作特殊情况下。此时如果线上想查看调试级别下的日志,又不能更改日志级别后重新发布该怎么办?   Spring Boot提供了日志级别动态配置功能,为我们的线上应用调试提供了很好的机制。
1878 0
下一篇
无影云桌面