SpringBoot面试题

159 阅读4分钟

SpringBoot面试题

1、SpringBoot是如何实现自动配置的?
(1)通过@SpringBootApplication引入@EnableAutoConfiguration注解,开启自动配置
(2)@EnableAutoConfiguration引入@Import注解,Spring容器启动时,会解析@Import注解
(3)@Import导入了deferredImportSelector,会将自动配置类放到最后加载,方便扩展和覆盖
(4)然后读取Meta-INF文件夹下的Spring.factories文件,过滤出其中的自动配置类
(5)通过@Conditional排除无效的自动配置类

2、SpringBoot启动过程?
(1)启动类中执行SpringApplication.run方法,创建SpringApplication对象。创建对象时,读取spring.factories文件内容,主要读取ApplicationListener和ApplicationContextInitializer的信息。
(2)运行run方法,读取配置文件,加载Ioc容器
(3)解析@Import注解,加载自动配置类
(4)创建web容器(默认有Tomcat、Jetty和Undertow)
(5)在这过程中会调用很多监听器对外扩展

3、SpringBoot内嵌Tomcat启动过程?
(1)Spring-boot-starter-web依赖会添加ServletWebServerFactoryAutoConfiguration自动配置类
(2)这个自动配置类通过@Import注解导入了内嵌web容器类,例如:EmbeddedTomcat,EmbeddedUntertow等。然后通过@ConditionalOnXXX注解过滤出可用的Web容器工厂,此工厂可以创建并启动Web容器
(3)像内嵌的Tomcat容器有一个TomcatServletWebServerFactory的Web容器工厂
(4)Springboot启动时,通过refreshContext方法加载Ioc容器,其中InvokeBeanFactoryPostProcessors方法会解析注解,注册符合条件的自动配置类,ServletWebServerFactoryAutoConfiguration也被注册
(5)ServletWebServerFactoryAutoConfiguration被注册后,通过@ConditionalOnXXX注解过滤出TomcatServletWebServerFactory类
(6)然后调用onRefresh方法,此方法中通过createWebServer方法拿到TomcatServletWebServerFactory的Bean,调用Bean中的getWebServer方法创建Tomcat服务,并且启动和监听

4、SpringBoot读取配置文件的方式?
(1)@Value注解:写在类的属性上
(2)@ConfigurationProperties注解:写在类定义上,用于批量赋值
(3)通过Environment这个Bean提供的getProperty方法,读取配置
(4)@PropertySources注解读取自定义的配置文件

5、SpringBoot可以同时处理的最大连接数是多少?
这与SpringBoot内嵌的Web容器有关。Web容器的连接池有四个关键参数,最小线程数,最大线程数,最大连接数和最大等待数。SpringBoot同时可以处理的最大连接数是Web容器连接池的最大连接数+最大等待数。但是,SpringBoot未必可以在同一时刻处理这么多的请求,这个要看连接池的最大线程数是多少。

6、在SpringBoot中自定义一个starter?
(1)创建一个Maven项目,添加需要的依赖
(2)写一个自动配置类,@ConditionalOnMissingBean注解表示没有MyService的Bean默认创建一个

@Configuration
@ConditionalOnClass(MyServer.class)
public class MyServerAutoConfiguration {

    @Value("${myserver.host:192.168.1.120}")
    priavte String host;
    
    @Value("${myserver.port:8800}")
    priavte String port;
    
    @Bean
    @ConditionalOnMissingBean
    public MyServer myServer() {
        MyService server =  new MyServer();
        server.setHost(this.host);
        server.setPort(this.port);
        return server;
    }
}

(4)写一个服务类

public class MyServer {
    private String host;
    private Integer port;
    
    public void setHost(String host) {
        this.host = host
    }
    
    public void setPort(Integer port) {
        this.port = port
    }
}

(5)在META-INF/Spring.factories文件中添加自动配置类信息

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.example.starter.MyServerAutoConfiguration

(6)项目打包发布到中央仓库

7、SpringBoot如何解决跨域?
(1)在controller接口上使用@CrossOrigin注解,写明跨域的来源
(2)实现WebMvcConfigurer接口的addCorsMappings方法,对批量的请求做跨域处理
(3)使用nginx反向代理解决跨域问题。假设前端是8081端口发送过来的请求,到nginx中被转发到8082端口的接口上

8、SpringBoot捕获全局异常?
(1)创建一个捕获全局异常类,使用@ControllerAdvice注解修饰
(2)在类中编写异常处理方法,使用@ExceptionHandler注解指定要处理的异常类型

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> handleRuntimeException(RuntimeException ex) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ex.getMessage());
    }

    @ExceptionHandler(MyCustomException.class)
    public ResponseEntity<String> handleCustomException(MyCustomException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
    }
}

9、SpringBoot读取配置文件的顺序?
(1)最高优先级读取与jar包在同一层级的config文件夹中的配置文件
(2)第二优先级读取与jar包在同一层级的配置文件
(3)第三优先级读取classpath下的config文件夹中的配置文件
(4)第四优先级读取classpath下的配置文件

10、SpringBoot的核心注解?
(1)@EnableAutoConfiguration
(2)@SpringBootApplication
(3)@SpringBootConfiguration
(4)@ConditionOnXXX

11、为什么SpringBoot的jar包可以直接运行?
(1)SpringBoot提供了插件Spring-Boot-Maven-Plugin,用于把程序打包成可执行jar包
(2)打成的jar包中包含了程序依赖的jar包,和一些程序启动相关的文件
(3)java -jar 命令会去到manifest文件中找到mainclass,这个是jar包的启动类JarLauncher
(4)JarLauncher类中有个launch方法,JVM会创建一个线程去执行launch方法,这个方法会去执行程序启动类中的main方法