SpringBoot启动成功后调用接口、方法

简介: SpringBoot启动成功后调用接口、方法

问题


  线上问题遇到一个接口第一次访问特别慢的问题,后来说是因为该接口加了某注解,所以第一次请求比较慢,初步解决办法就是启动后先请求一次就好了。


代码


模拟测试接口


  @RequestMapping("/hello")
  public String hello() {
    return LocalDateTime.now().toString();
  }


核心接口CommandLineRunner


package com.example.autorequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
 * @author chaird
 * @create 2020-07-31 22:43
 */
@Component
@Slf4j
public class StartAutoRequestService implements CommandLineRunner {
  @Override
  public void run(String... args) throws Exception {
    String httpUrl = "http://localhost:8082/hello";
    // 链接
    HttpURLConnection connection = null;
    InputStream is = null;
    BufferedReader br = null;
    StringBuffer result = new StringBuffer();
    try {
      // 创建连接
      URL url = new URL(httpUrl);
      connection = (HttpURLConnection) url.openConnection();
      // 设置请求方式
      connection.setRequestMethod("GET");
      // 设置连接超时时间
      connection.setReadTimeout(15000);
      // 开始连接
      connection.connect();
      // 获取响应数据
      if (connection.getResponseCode() == 200) {
        // 获取返回的数据
        is = connection.getInputStream();
        if (null != is) {
          br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
          String temp = null;
          while (null != (temp = br.readLine())) {
            result.append(temp);
          }
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (null != br) {
        try {
          br.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != is) {
        try {
          is.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      // 关闭远程连接
      connection.disconnect();
    }
    System.out.println(result.toString());
  }
}

原理


首先在自己实现CommandLineRunner接口的类的run方法里打个断点,看一下调用栈,这样好知道在哪打断点


5.png


在上图箭头处的方法的第一行打断点

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    configureHeadlessProperty();
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
      ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
      configureIgnoreBeanInfo(environment);
      Banner printedBanner = printBanner(environment);
      context = createApplicationContext();
      exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
          new Class[] { ConfigurableApplicationContext.class }, context);
      prepareContext(context, environment, listeners, applicationArguments, printedBanner);
      refreshContext(context);
            //断点走到这,此时控制台已经打印出Tomcat started on port(s): 8082 (http) with context path ''
            //断点走到这,此时控制台已经打印出Tomcat started on port(s): 8082 (http) with context path ''
           //断点走到这,此时控制台已经打印出Tomcat started on port(s): 8082 (http) with context path ''
      afterRefresh(context, applicationArguments);
      stopWatch.stop();
      if (this.logStartupInfo) {
        new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
      }
      listeners.started(context);
            //开始调用实现CommandLineRunner接口的方法
            //开始调用实现CommandLineRunner接口的方法
            //开始调用实现CommandLineRunner接口的方法
      callRunners(context, applicationArguments);
    }
    catch (Throwable ex) {
    }
    try {
      listeners.running(context);
    }
    catch (Throwable ex) {
    }
    return context;
  }

进入上图的callRunners方法


  private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<Object> runners = new ArrayList<>();
    runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    //拿到实现CommandLineRunner接口的实现类
    runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    AnnotationAwareOrderComparator.sort(runners);
    for (Object runner : new LinkedHashSet<>(runners)) {
      if (runner instanceof ApplicationRunner) {
        callRunner((ApplicationRunner) runner, args);
      }
      if (runner instanceof CommandLineRunner) {
           //调用方法,此时在跟进去就进入自己写的方法里了
        callRunner((CommandLineRunner) runner, args);
      }
    }
  }
目录
相关文章
|
3月前
|
存储 算法 安全
SpringBoot 接口加密解密实现
【10月更文挑战第18天】
|
2月前
|
Java 开发者 Spring
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
54 1
|
3月前
|
存储 安全 Java
|
3月前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
103 0
|
4月前
|
Java 应用服务中间件 Spring
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
IDEA 工具 启动 spring boot 的 main 方法报错。已解决
|
4月前
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
|
4月前
|
存储 前端开发 Java
springboot文件上传和下载接口的简单思路
本文介绍了在Spring Boot中实现文件上传和下载接口的简单思路。文件上传通过`MultipartFile`对象获取前端传递的文件并存储,返回对外访问路径;文件下载通过文件的uuid名称读取文件,并通过流的方式输出,实现文件下载功能。
springboot文件上传和下载接口的简单思路
|
4月前
|
存储 数据采集 Java
Spring Boot 3 实现GZIP压缩优化:显著减少接口流量消耗!
在Web开发过程中,随着应用规模的扩大和用户量的增长,接口流量的消耗成为了一个不容忽视的问题。为了提升应用的性能和用户体验,减少带宽占用,数据压缩成为了一个重要的优化手段。在Spring Boot 3中,通过集成GZIP压缩技术,我们可以显著减少接口流量的消耗,从而优化应用的性能。本文将详细介绍如何在Spring Boot 3中实现GZIP压缩优化。
472 6
|
3月前
|
存储 NoSQL Java
Spring Boot项目中使用Redis实现接口幂等性的方案
通过上述方法,可以有效地在Spring Boot项目中利用Redis实现接口幂等性,既保证了接口操作的安全性,又提高了系统的可靠性。
67 0
|
4月前
|
Java 网络架构
springboot配合thymeleaf,调用接口不跳转页面只显示文本
springboot配合thymeleaf,调用接口不跳转页面只显示文本
167 0