SpringBoot高级面试题-2024

发布于:2024-03-28 ⋅ 阅读:(25) ⋅ 点赞:(0)

SpringBoot如何自定义Starter

  1. 创建项目结构: 创建一个Maven项目,确保项目结构符合标准的约定。通常,项目结构包括src/main/java用于存放Java代码和src/main/resources用于存放资源文件。
  2. 编写自动配置类: 创建一个自动配置类,该类负责配置自定义Starter的功能。在自动配置类上使用@Configuration注解,并通过其他注解如@ConditionalOnClass@ConditionalOnProperty等来定义条件,以确保只有在满足特定条件时才会应用配置。
  3. 提供属性配置: 如果您的Starter需要配置属性,可以在src/main/resources/application.propertiessrc/main/resources/application.yml中定义属性。这些属性可以在自动配置类中使用@Value注解注入。
  4. 创建META-INF/spring.factories文件: 在项目的资源目录中创建META-INF/spring.factories文件。在这个文件中,注册您的自动配置类,以便Spring Boot能够自动识别和加载它。
  5. 定义Starter依赖: 在自定义Starter的pom.xml文件中,定义Spring Boot的核心依赖以及您的Starter所依赖的其他库。
  6. 测试和文档: 编写单元测试和集成测试,以确保自定义Starter的功能和配置正确。同时,提供详细的文档和示例,以便用户能够正确配置和使用您的Starter。
  7. 发布到仓库: 将自定义Starter打包,并发布到Maven中央仓库或私有仓库,以便其他项目可以引入和使用。

总之,自定义一个Spring Boot Starter需要遵循上述步骤,其中创建META-INF/spring.factories文件是关键,因为它告诉Spring Boot如何自动装配您的功能。这样,其他项目可以方便地引入您的Starter,实现功能的快速集成。

SpringBoot的启动原理?

  1. 运行Main方法: 应用程序启动始于Main方法的执行。在Main方法中,创建了一个SpringApplication实例,用于引导应用程序的启动。同时,SpringApplication会根据spring.factories文件加载并注册监听器、ApplicationContextInitializer等扩展接口实现。
  2. 运行run方法: 运行SpringApplication的run方法是应用程序启动的入口。在这一步,Spring Boot会 启动Spring进而创建内置tomcat,进去run方法后还做了很多其他事:
  3. Spring Boot会读取和解析环境变量、配置文件(如application.propertiesapplication.yml)等,以获取应用程序的配置信息。
  4. 之后再创建ApplicationContext也就是我们熟知的Spring上下文: 在这一步,Spring Boot会根据应用程序的类型(例如,Web应用程序)创建相应的ApplicationContext。对于Web应用程序,通常创建的是ServletWebServerApplicationContext
  5. 预初始化上下文: Spring Boot会将启动类作为配置类,读取并注册为BeanDefinition,这使得Spring容器可以识别应用程序的配置。
  6. 调用refresh: 此时,Spring Boot调用了refresh方法来加载和初始化Spring容器。在这一过程中,会执行一系列操作,包括解析@Import注解以加载自动配置类,创建和注册BeanDefinition等。
  7. 创建内置servlet容器: 如果应用程序是一个Web应用程序,Spring Boot会在这一步创建内置的servlet容器(例如Tomcat),以便应用程序可以接受HTTP请求。这个容器将被Spring Boot自动配置,并且可以通过配置进行自定义。
  8. 监听器和扩展点: 在整个启动过程中,Spring Boot会调用各种监听器和扩展点,这些组件可以用来对应用程序进行扩展和定制。例如,您可以使用监听器来处理应用程序启动和关闭事件,或者使用ApplicationContextInitializer来自定义ApplicationContext的初始化。

为什么SpringBoot的jar可以直接运行?

  1. 第一个关键点: Spring Boot提供了一个Maven插件(spring-boot-maven-plugin),用于将应用程序打包成可执行的JAR文件。通过执行mvn clean package等命令,可以轻松生成可执行JAR。
  2. 第二个关键点: 打包生成的JAR文件通常是"Fat JAR"或"Uber JAR",这意味着它包含了应用程序的所有依赖项,包括第三方库和Spring Boot框架本身。这样,JAR文件就成了一个自包含的单一文件。
  3. 第三个关键点: JAR文件包含一个名为MANIFEST.MF的清单文件,其中包含了关于JAR文件的元数据信息。其中,主要的信息是Main-Class,它指定了启动应用程序的主类。
  4. 第四个关键点: Spring Boot的可执行JAR文件通常由JarLauncher类启动。JarLauncher负责创建一个类加载器(LaunchedURLClassLoader),加载boot-lib目录下的JAR文件,包括Spring Boot loader相关的类。然后,它在一个新线程中启动应用程序的Main方法,实现应用程序的启动。、
  5. 第五个关键点:当执行Main方法最终会加载Spring容器、进而创建内嵌Tomcat进行阻塞线程使我们jar包完成web应用的启动

Springboot的自动配置原理?

  1. 引入@EnableAutoConfiguration: 在Spring Boot应用程序的主配置类(通常是带有@SpringBootApplication注解的类)中,通常会引入@EnableAutoConfiguration注解,该注解负责启动自动配置功能。
  2. @EnableAutoConfiguration引入了@Import: @EnableAutoConfiguration注解实际上是通过@Import注解引入的。这意味着它会导入其他配置类,这些配置类包含了Spring Boot自动配置的逻辑。
  3. 解析@Import注解: 当Spring容器启动时,会解析@Import注解,并加载相应的配置。
  4. deferredImportSelector: 通过@Import导入的配置类中可能包含了一个deferredImportSelector,它的作用是确保Spring Boot的自动配置类在最后加载,以便方便扩展和覆盖。
  5. 读取META-INF/spring.factories文件: Spring Boot通过SPI(Service Provider Interface)机制,读取类路径下的META-INF/spring.factories文件,该文件包含了各种自动配置类的配置。
  6. 过滤出AutoConfigurationClass: 从spring.factories文件中,Spring Boot会过滤出所有AutoConfigurationClass类型的类,这些类包含了自动配置的具体实现。
  7. 条件化加载: 最后,Spring Boot会根据条件(@ConditionalXXX注解)来排除或包含特定的自动配置类。这些条件会根据应用程序的环境和配置动态生效。

总结起来,Spring Boot的自动配置原理是通过@EnableAutoConfiguration注解引入自动配置逻辑,然后解析@Import注解,加载各种配置类,包括deferredImportSelector和自动配置类。通过SPI机制读取spring.factories文件,过滤出自动配置类,并根据条件化配置来动态加载这些类,从而实现自动配置的功能。这种机制使得Spring Boot应用程序可以根据环境和需求自动配置,极大地简化了开发和部署的工作。

SpringBoot为什么默认使用CGLIB

  • 无需接口: CGLIB能够代理那些没有实现接口的类,而JDK动态代理只能代理实现了接口的类。这使得Spring Boot可以更灵活地使用代理,而无需依赖于接口。
  • AOP支持: Spring Boot广泛使用AOP(面向切面编程)来处理日志、事务、安全性等横切关注点。CGLIB更适合创建AOP代理,因为它可以代理普通的类而不仅仅是接口,在开发中如果通过反射获得代理目标方法的注解,如果用JDK动态代理将导致无法获取。
  • 可以代理本类方法:这意味着即使在同一个类中调用了另一个方法,仍然可以触发代理的行为。这对于某些特定的AOP需求非常有用,因为它允许您在同一类中的方法之间应用切面。这种能力被称为"自我调用"或"内部调用"的代理。
  • 方法调用性能: 一旦代理对象创建完成,实际的方法调用性能可能会因代理方式而异。在JDK 1.8之后,JDK动态代理的方法调用性能相对较好,但CGLIB仍然可能更快,因为CGlib是直接调用父类方法即目标方法,无需像JDK代理还要通过反射进行内部方法栈调用才能到目标方法。

Spring和SpringBoot的关系和区别?

关系:

  1. Spring是框架,Spring Boot是个脚手架: Spring是一个全功能的Java应用程序框架,旨在帮助开发人员构建各种类型的应用程序,包括Web应用、企业级应用、批处理应用等。Spring提供了大量的组件和功能,但需要开发人员进行详细的配置和集成。Spring Boot则是一个脚手架工具,它基于Spring框架,旨在简化Spring应用程序的初始配置和开发过程,提供了自动化配置和约定优于配置的特性。
  2. Spring Boot构建在Spring之上: Spring Boot不是一个独立的框架,而是建立在Spring框架之上的工具。它使用了Spring的核心功能,如依赖注入、面向切面编程、事务管理等。因此,Spring Boot项目可以充分利用Spring框架的功能,但更容易启动和运行。

区别:

  1. 配置方式: Spring通常需要大量的XML配置或Java注解来定义应用程序的配置。相比之下,Spring Boot采用了"约定优于配置"的原则,大部分配置都可以通过默认值和自动配置来完成,从而减少了配置的复杂性。
  2. 开发速度: Spring Boot旨在提高开发速度,因此它降低了开发人员的学习曲线,并提供了内置的Starter和自动配置,使开发更加快速和高效。Spring需要更多的手动配置和集成工作。
  3. 内置Web容器: Spring Boot内置了多个内嵌式Web容器,如Tomcat、Jetty、Undertow等,可以轻松创建独立的可执行JAR文件或WAR文件,而不需要外部Web服务器。Spring通常需要外部Web服务器的部署。

总的来说,Spring是一个全功能的Java应用程序框架,而Spring Boot是一个用于简化Spring应用程序开发的工具。Spring Boot通过自动化配置、约定优于配置的原则、内置Web容器等功能,使得开发和部署Spring应用程序变得更加快速和便捷,特别适用于微服务和快速原型开发。开发人员可以根据项目的需求选择使用Spring框架、Spring Boot,或两者结合使用。

谈谈你对SpringBoot的理解?

  1. 内置Starter和自动配置: Spring Boot提供了丰富的内置Starter,这些Starter是预定义的依赖集合,可以轻松集成各种主流框架和技术。同时,Spring Boot通过自动配置大大减少了繁琐的配置工作,让开发人员可以直接开箱即用。
  2. 零XML配置: Spring Boot采用JavaConfig的方式进行开发,不需要编写大量的XML配置文件。这种零XML的开发方式让开发更加简洁和可读,同时提高了可维护性。
  3. 内置Web容器: Spring Boot内置了多个Web容器,如Tomcat、Jetty、Undertow等,无需外部Web服务器。这意味着您可以将应用程序打包成可执行的JAR文件,直接运行而不需要额外的容器配置,从而简化了部署过程。
  4. 微服务支持: Spring Boot与Spring Cloud结合使用,可以轻松快速构建和部署微服务架构。
  5. 依赖版本管理: Spring Boot帮助开发人员管理了常用第三方依赖的版本,防止出现版本冲突问题。这样,您可以更专注于业务逻辑,而不用担心依赖的版本兼容性。
  6. 监控和管理: Spring Boot自带了监控功能,包括应用程序运行状况监控、内存使用情况、线程池状态、HTTP请求统计等。此外,Spring Boot还提供了优雅关闭应用程序的方式,使得应用程序的管理更加便捷。

总的来说,Spring Boot旨在提供一个快速、高效、开箱即用的开发环境,使开发人员能够更加专注于业务逻辑的实现而不必花费太多时间在繁琐的配置和集成上。它的设计理念是"约定优于配置",通过合理的默认配置和内置功能,让开发变得更加简单和愉快。

本文含有隐藏内容,请 开通VIP 后查看