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

SpringBoot高频面试20问:从自动配置到分布式事务考点解析

一、Spring Boot 自动配置相关问题

1. 什么是 Spring Boot 自动配置?

Spring Boot 自动配置是 Spring Boot 框架的核心特性之一,它可以根据类路径中的依赖、配置文件以及其他条件,自动为应用程序提供合理的默认配置。例如,当我们在项目中添加了 Spring Data JPA 的依赖后,Spring Boot 会自动配置数据源、JPA 实体管理器等相关组件,无需我们手动编写大量的配置代码。

2. Spring Boot 自动配置的原理是什么?

Spring Boot 自动配置主要基于 Spring 的条件注解(如 @ConditionalOnClass@ConditionalOnMissingBean 等)和 @EnableAutoConfiguration 注解实现。当应用启动时,@EnableAutoConfiguration 注解会触发自动配置机制,Spring Boot 会扫描 META - INF/spring.factories 文件,该文件中定义了所有自动配置类的全限定名。然后,Spring Boot 会根据条件注解的判断结果,决定是否加载这些自动配置类。

以下是一个简单的示例代码,展示了如何使用 @ConditionalOnClass 注解:

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnClass(name = "com.example.SomeClass")
public class MyAutoConfiguration {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

在上述代码中,只有当类路径中存在 com.example.SomeClass 时,MyAutoConfiguration 类才会被加载,myService 方法才会创建 MyService 实例。

3. 如何禁用 Spring Boot 自动配置?

如果我们不希望某些自动配置类被加载,可以使用 @SpringBootApplication 注解的 exclude 属性或者 excludeName 属性来排除指定的自动配置类。

示例代码如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;

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

在上述代码中,我们排除了 DataSourceAutoConfiguration 类,这样 Spring Boot 就不会自动配置数据源。

二、Spring Boot 核心注解相关问题

4. 请解释 @SpringBootApplication 注解的作用

@SpringBootApplication 是一个组合注解,它包含了 @Configuration@EnableAutoConfiguration@ComponentScan 三个注解的功能。

  • @Configuration:表示该类是一个配置类,相当于 Spring 的 XML 配置文件。
  • @EnableAutoConfiguration:启用 Spring Boot 的自动配置功能。
  • @ComponentScan:扫描指定包及其子包下的所有组件(如 @Component@Service@Repository 等注解标注的类)。

示例代码如下:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

5. @Component@Service@Repository@Controller 注解有什么区别?

  • @Component:是一个通用的组件注解,用于标注任意 Spring 组件。
  • @Service:通常用于标注业务逻辑层的类,是 @Component 的派生注解。
  • @Repository:用于标注数据访问层的类,也是 @Component 的派生注解,Spring 会自动处理 @Repository 注解标注的类抛出的数据访问异常。
  • @Controller:用于标注控制器层的类,同样是 @Component 的派生注解,主要用于处理 HTTP 请求。

示例代码如下:

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

@Component
public class MyComponent {
    // 组件类
}

@Service
public class MyService {
    // 业务逻辑类
}

@Repository
public class MyRepository {
    // 数据访问类
}

@Controller
public class MyController {
    // 控制器类
}

三、Spring Boot 配置文件相关问题

6. Spring Boot 支持哪些配置文件格式?

Spring Boot 支持多种配置文件格式,主要包括:

  • application.properties:是最常用的配置文件格式,使用键值对的形式进行配置。
  • application.ymlapplication.yaml:使用 YAML 格式进行配置,具有更好的可读性和层次性。

示例 application.properties 文件:

server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=123456

示例 application.yml 文件:

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: 123456

7. 如何在 Spring Boot 中使用多环境配置?

Spring Boot 支持使用不同的配置文件来区分不同的环境,如开发环境、测试环境和生产环境。可以通过 application-{profile}.propertiesapplication-{profile}.yml 来定义不同环境的配置文件,其中 {profile} 是环境名称。

例如,创建 application-dev.properties 用于开发环境,application-prod.properties 用于生产环境。

application-dev.properties

server.port=8081

application-prod.properties

server.port=80

在启动应用时,可以通过 spring.profiles.active 属性指定要使用的环境配置,例如在命令行中使用以下命令启动应用:

java -jar myapp.jar --spring.profiles.active=dev

四、Spring Boot 与数据库相关问题

8. 如何在 Spring Boot 中配置数据源?

在 Spring Boot 中配置数据源非常简单,只需要在配置文件中添加数据源的相关信息即可。以下是使用 application.properties 配置 MySQL 数据源的示例:

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

9. 什么是 Spring Data JPA?如何在 Spring Boot 中使用它?

Spring Data JPA 是 Spring 提供的一个简化 JPA 开发的框架,它可以帮助我们减少数据访问层的代码编写。在 Spring Boot 中使用 Spring Data JPA,只需要添加相应的依赖,并定义实体类和 Repository 接口即可。

首先,在 pom.xml 中添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

然后,定义实体类:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Integer age;

    // 省略 getter 和 setter 方法
}

最后,定义 Repository 接口:

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}

10. 如何在 Spring Boot 中实现事务管理?

在 Spring Boot 中实现事务管理非常简单,只需要在服务层的方法上添加 @Transactional 注解即可。

示例代码如下:

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

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void saveUser(User user) {
        userRepository.save(user);
    }
}

五、Spring Boot 与微服务相关问题

11. 什么是 Spring Cloud?它与 Spring Boot 有什么关系?

Spring Cloud 是一个基于 Spring Boot 构建的微服务工具集,它提供了一系列的组件,如服务发现(Eureka、Consul)、配置管理(Config Server)、负载均衡(Ribbon)、熔断器(Hystrix)等,用于帮助开发者快速构建分布式系统。Spring Boot 为 Spring Cloud 提供了基础的开发框架,使得 Spring Cloud 的组件可以方便地集成到 Spring Boot 应用中。

12. 如何在 Spring Boot 中实现服务注册与发现?

可以使用 Spring Cloud Eureka 来实现服务注册与发现。以下是实现步骤:

1. 创建 Eureka Server

首先,创建一个 Spring Boot 项目,添加以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

然后,在主类上添加 @EnableEurekaServer 注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
2. 创建 Eureka Client

创建另一个 Spring Boot 项目,添加以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在配置文件中添加 Eureka Server 的地址:

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/

在主类上添加 @EnableEurekaClient 注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.client.EnableEurekaClient;

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

六、Spring Boot 性能优化相关问题

13. 如何优化 Spring Boot 应用的启动时间?

  • 减少自动配置类的加载:可以通过 @SpringBootApplicationexclude 属性排除不必要的自动配置类。
  • 使用 Spring Boot DevTools:它可以在开发过程中提供快速重启的功能。
  • 优化依赖:只添加必要的依赖,避免引入过多的无用依赖。

14. 如何进行 Spring Boot 应用的性能监控?

可以使用 Spring Boot Actuator 来进行性能监控。添加以下依赖:

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

在配置文件中开启所有端点:

management.endpoints.web.exposure.include=*

访问 http://localhost:8080/actuator 可以查看所有可用的端点信息,如 /actuator/health 可以查看应用的健康状态,/actuator/metrics 可以查看应用的性能指标。

七、Spring Boot 分布式事务相关问题

15. 什么是分布式事务?

分布式事务是指在分布式系统中,涉及多个服务或资源的事务操作,需要保证这些操作要么全部成功,要么全部失败。例如,在一个电商系统中,用户下单时需要同时更新订单表和库存表,这两个操作可能分别在不同的服务中执行,需要使用分布式事务来保证数据的一致性。

16. 常见的分布式事务解决方案有哪些?

  • 两阶段提交(2PC):分为准备阶段和提交阶段,协调者会先询问所有参与者是否可以提交事务,只有当所有参与者都准备好后,才会进行提交操作。
  • 三阶段提交(3PC):在两阶段提交的基础上增加了一个预准备阶段,减少了参与者的阻塞时间。
  • TCC(Try - Confirm - Cancel):将一个业务操作分为三个步骤,Try 阶段尝试执行操作,Confirm 阶段确认操作,Cancel 阶段取消操作。
  • 消息事务:通过消息队列来保证事务的最终一致性,例如 RocketMQ 的事务消息。

17. 如何在 Spring Boot 中使用 Seata 实现分布式事务?

Seata 是一个开源的分布式事务解决方案,以下是在 Spring Boot 中使用 Seata 实现分布式事务的步骤:

1. 下载并启动 Seata Server

从 Seata 的 GitHub 仓库下载 Seata Server,解压后启动 seata-server.sh(Linux)或 seata-server.bat(Windows)。

2. 添加 Seata 依赖

pom.xml 中添加以下依赖:

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.4.2</version>
</dependency>
3. 配置 Seata

application.properties 中添加以下配置:

seata.tx-service-group=my_test_tx_group
seata.service.vgroup-mapping.my_test_tx_group=default
seata.service.grouplist.default=127.0.0.1:8091
4. 在业务方法上添加 @GlobalTransactional 注解
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    @GlobalTransactional
    public void createOrder() {
        // 业务逻辑
    }
}

八、Spring Boot 安全相关问题

18. 如何在 Spring Boot 中实现安全认证?

可以使用 Spring Security 来实现安全认证。添加以下依赖:

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

创建一个配置类来配置安全规则:

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.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
           .authorizeRequests()
               .antMatchers("/public/**").permitAll()
               .anyRequest().authenticated()
               .and()
           .formLogin()
               .and()
           .httpBasic();
        return http.build();
    }
}

19. 如何使用 JWT 进行身份验证?

JWT(JSON Web Token)是一种用于身份验证的开放标准。以下是在 Spring Boot 中使用 JWT 进行身份验证的步骤:

1. 添加依赖
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
    <scope>runtime</scope>
</dependency>
2. 创建 JWT 工具类
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtils {
    private static final String SECRET_KEY = "mysecretkey";
    private static final long EXPIRATION_TIME = 86400000; // 24 hours

    public static String generateToken(String username) {
        return Jwts.builder()
               .setSubject(username)
               .setIssuedAt(new Date(System.currentTimeMillis()))
               .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
               .signWith(SignatureAlgorithm.HS512, SECRET_KEY)
               .compact();
    }

    public static String getUsernameFromToken(String token) {
        return Jwts.parser()
               .setSigningKey(SECRET_KEY)
               .parseClaimsJws(token)
               .getBody()
               .getSubject();
    }
}
3. 实现 JWT 过滤器
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    private final UserDetailsService userDetailsService;

    public JwtAuthenticationFilter(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            String username = JwtUtils.getUsernameFromToken(token);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                if (JwtUtils.validateToken(token, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}

九、Spring Boot 部署相关问题

20. 如何将 Spring Boot 应用部署到 Docker 容器中?

以下是将 Spring Boot 应用部署到 Docker 容器中的步骤:

1. 创建 Dockerfile

在项目根目录下创建 Dockerfile 文件,内容如下:

# 使用基础镜像
FROM openjdk:11
# 将打包好的 JAR 文件复制到容器中
COPY target/myapp.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动应用
ENTRYPOINT ["java", "-jar", "app.jar"]
2. 构建 Docker 镜像

在项目根目录下执行以下命令构建 Docker 镜像:

docker build -t myapp:1.0 .
3. 运行 Docker 容器

执行以下命令运行 Docker 容器:

docker run -p 8080:8080 myapp:1.0
Logo

更多推荐