10 个高频 Spring Boot 面试题解析:从自动装配到热部署原理

🎓博主介绍:Java、Python、js全栈开发 “多面手”,精通多种编程语言和技术,痴迷于人工智能领域。秉持着对技术的热爱与执着,持续探索创新,愿在此分享交流和学习,与大家共进步。
📖全栈开发环境搭建运行攻略:多语言一站式指南(环境搭建+运行+调试+发布+保姆级详解)
👉感兴趣的可以先收藏起来,希望帮助更多的人
在这里插入图片描述

10 个高频 Spring Boot 面试题解析:从自动装配到热部署原理

一、Spring Boot 自动装配原理

1.1 什么是自动装配

Spring Boot 的自动装配是指 Spring Boot 根据项目中添加的依赖,自动配置 Spring 应用程序的功能。例如,当我们在项目中添加了 Spring Data JPA 的依赖,Spring Boot 会自动配置数据源、JPA 实体管理器等。

1.2 自动装配的实现机制

Spring Boot 的自动装配主要通过 @EnableAutoConfiguration 注解实现。该注解会触发 Spring Boot 的自动配置机制,它会扫描 META-INF/spring.factories 文件,该文件中定义了一系列的自动配置类。

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@SpringBootApplication 注解包含了 @EnableAutoConfiguration 注解,因此在启动 Spring Boot 应用时,会自动进行自动装配。

1.3 自动装配的条件注解

Spring Boot 还提供了一系列的条件注解,如 @ConditionalOnClass@ConditionalOnMissingBean 等,用于控制自动配置类的加载。例如:

@Configuration
@ConditionalOnClass(JdbcTemplate.class)
public class JdbcAutoConfiguration {
    // 配置 JdbcTemplate 的相关 Bean
}

上述代码表示只有当 JdbcTemplate 类存在于类路径中时,才会加载 JdbcAutoConfiguration 配置类。

二、Spring Boot Starter 原理

2.1 什么是 Starter

Spring Boot Starter 是一种依赖集合,它将相关的依赖打包在一起,方便开发者使用。例如,spring-boot-starter-web 包含了 Spring MVC、Tomcat 等相关依赖,开发者只需要添加该 Starter 依赖,就可以快速搭建一个 Web 应用。

2.2 Starter 的实现原理

Starter 本质上是一个 Maven 或 Gradle 依赖,它通过 pom.xmlbuild.gradle 文件来管理依赖。例如,spring-boot-starter-webpom.xml 文件中包含了以下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-json</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
</dependencies>

通过这种方式,开发者只需要添加一个 Starter 依赖,就可以引入多个相关依赖。

三、Spring Boot 的配置文件加载顺序

3.1 配置文件类型

Spring Boot 支持多种配置文件类型,如 application.propertiesapplication.yml 等。

3.2 配置文件加载顺序

Spring Boot 会按照以下顺序加载配置文件:

  1. 命令行参数
  2. SPRING_APPLICATION_JSON 中的属性
  3. ServletConfig 初始化参数
  4. ServletContext 初始化参数
  5. JNDI 属性(java:comp/env
  6. Java 系统属性(System.getProperties()
  7. 操作系统环境变量
  8. RandomValuePropertySource 提供的随机属性
  9. 打包在 jar 外部的 application-{profile}.propertiesapplication-{profile}.yml 文件
  10. 打包在 jar 内部的 application-{profile}.propertiesapplication-{profile}.yml 文件
  11. 打包在 jar 外部的 application.propertiesapplication.yml 文件
  12. 打包在 jar 内部的 application.propertiesapplication.yml 文件
  13. @Configuration 类上的 @PropertySource 注解指定的属性源
  14. 默认属性(通过 SpringApplication.setDefaultProperties 指定)

3.3 示例代码

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(MyApplication.class);
        app.setDefaultProperties(Collections.singletonMap("server.port", "8081"));
        app.run(args);
    }
}

上述代码通过 setDefaultProperties 方法设置了默认属性。

四、Spring Boot 如何实现日志管理

4.1 默认日志框架

Spring Boot 默认使用 Logback 作为日志框架。当我们创建一个 Spring Boot 项目时,会自动引入 Logback 的依赖。

4.2 配置日志

我们可以通过 application.propertiesapplication.yml 文件来配置日志。例如,在 application.properties 中配置日志级别:

logging.level.root=INFO
logging.level.com.example=DEBUG

上述代码将根日志级别设置为 INFO,将 com.example 包下的日志级别设置为 DEBUG

4.3 自定义日志配置文件

我们也可以自定义 Logback 的配置文件,只需要在 src/main/resources 目录下创建 logback.xml 文件。例如:

<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>

五、Spring Boot 如何集成 MyBatis

5.1 添加依赖

pom.xml 中添加 MyBatis 和 MyBatis Spring Boot Starter 的依赖:

<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.3.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

5.2 配置数据源

application.properties 中配置数据源信息:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

5.3 创建实体类和 Mapper 接口

创建实体类:

public class User {
    private Long id;
    private String name;
    // 省略 getter 和 setter 方法
}

创建 Mapper 接口:

import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface UserMapper {
    List<User> findAll();
}

5.4 创建 Mapper XML 文件

src/main/resources 目录下创建 mapper 目录,并在该目录下创建 UserMapper.xml 文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
    <select id="findAll" resultType="com.example.entity.User">
        SELECT * FROM user
    </select>
</mapper>

5.5 使用 Mapper 接口

在 Service 层中使用 Mapper 接口:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public List<User> findAllUsers() {
        return userMapper.findAll();
    }
}

六、Spring Boot 如何实现异步方法调用

6.1 启用异步支持

在 Spring Boot 主类上添加 @EnableAsync 注解:

@SpringBootApplication
@EnableAsync
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

6.2 创建异步方法

在需要异步执行的方法上添加 @Async 注解:

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class AsyncService {
    @Async
    public void asyncMethod() {
        try {
            Thread.sleep(5000);
            System.out.println("异步方法执行完成");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

6.3 调用异步方法

在其他类中调用异步方法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CallerService {
    @Autowired
    private AsyncService asyncService;

    public void callAsyncMethod() {
        asyncService.asyncMethod();
        System.out.println("主线程继续执行");
    }
}

七、Spring Boot 如何实现定时任务

7.1 启用定时任务支持

在 Spring Boot 主类上添加 @EnableScheduling 注解:

@SpringBootApplication
@EnableScheduling
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

7.2 创建定时任务方法

在需要定时执行的方法上添加 @Scheduled 注解:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class ScheduledService {
    @Scheduled(fixedRate = 5000)
    public void fixedRateTask() {
        System.out.println("定时任务每隔 5 秒执行一次");
    }

    @Scheduled(cron = "0 0 12 * * ?")
    public void cronTask() {
        System.out.println("定时任务每天中午 12 点执行一次");
    }
}

八、Spring Boot 如何实现缓存管理

8.1 启用缓存支持

在 Spring Boot 主类上添加 @EnableCaching 注解:

@SpringBootApplication
@EnableCaching
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

8.2 使用缓存注解

在需要缓存的方法上添加 @Cacheable@CachePut@CacheEvict 等注解:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class CacheService {
    @Cacheable("users")
    public User getUserById(Long id) {
        // 模拟从数据库中查询用户
        System.out.println("从数据库中查询用户,ID: " + id);
        return new User(id, "John");
    }
}

九、Spring Boot 如何实现安全认证

9.1 添加 Spring Security 依赖

pom.xml 中添加 Spring Security 的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

9.2 配置安全认证

创建一个配置类,继承 WebSecurityConfigurerAdapter 类,并覆盖 configure 方法:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
           .authorizeRequests()
               .antMatchers("/public/**").permitAll()
               .anyRequest().authenticated()
               .and()
           .formLogin()
               .and()
           .httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

9.3 创建用户和角色

在配置类中创建用户和角色:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
           .inMemoryAuthentication()
               .withUser("user")
               .password(passwordEncoder().encode("password"))
               .roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
           .authorizeRequests()
               .antMatchers("/public/**").permitAll()
               .anyRequest().authenticated()
               .and()
           .formLogin()
               .and()
           .httpBasic();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

十、Spring Boot 热部署原理及实现

10.1 热部署原理

Spring Boot 热部署的原理是通过使用 Spring Loaded 或 DevTools 来实现的。当代码发生变化时,热部署工具会重新加载类,而不需要重启整个应用。

10.2 使用 DevTools 实现热部署

pom.xml 中添加 DevTools 的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

当我们修改代码后,IDE 会自动编译代码,DevTools 会检测到类文件的变化,并重新加载修改后的类。

10.3 注意事项

  • DevTools 会在开发环境中自动生效,生产环境中不会生效。
  • 某些情况下,如修改配置文件,可能需要手动重启应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fanxbl957

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值