Skip to content

Spring Boot面试题

1. Spring Boot的基本概念

问题:什么是Spring Boot?

答案

  • Spring Boot:基于Spring框架的快速开发框架,简化了Spring应用的配置和部署。
  • 特点
    • 自动配置:根据项目依赖自动配置Spring应用。
    • 起步依赖:提供一系列的starter依赖,简化依赖管理。
    • 内嵌服务器:内置Tomcat、Jetty等服务器,无需部署WAR包。
    • 生产就绪:提供监控、健康检查等生产就绪功能。
    • 无代码生成和XML配置:使用约定优于配置的原则。

2. Spring Boot的自动配置

问题:Spring Boot的自动配置原理是什么?

答案

  • 自动配置:Spring Boot根据类路径下的jar包和类,自动配置Spring应用。
  • 原理
    • @EnableAutoConfiguration:启用自动配置。
    • @Conditional:根据条件决定是否加载配置。
    • spring.factories:定义自动配置类。
    • @ConfigurationProperties:绑定配置属性。

3. Spring Boot的起步依赖

问题:什么是Spring Boot的起步依赖?

答案

  • 起步依赖:Spring Boot提供的一系列依赖,简化了依赖管理。
  • 作用
    • 避免版本冲突。
    • 简化依赖配置。
    • 提供合理的默认配置。

示例

xml
<!-- Web起步依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 数据库起步依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

4. Spring Boot的配置文件

问题:Spring Boot的配置文件有哪些?

答案

  • application.properties:properties格式的配置文件。
  • application.yml:YAML格式的配置文件。
  • application-{profile}.properties/yml:特定环境的配置文件。

示例

properties
# application.properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=123456
yaml
# application.yml
server:
  port: 8080

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

5. Spring Boot的Profile

问题:什么是Spring Boot的Profile?

答案

  • Profile:用于区分不同环境的配置,如开发、测试、生产环境。
  • 使用方式

示例

properties
# application-dev.properties
server.port=8080

# application-test.properties
server.port=8081

# application-prod.properties
server.port=80

# 激活Profile
spring.profiles.active=dev

6. Spring Boot的启动类

问题:Spring Boot的启动类有什么特点?

答案

  • @SpringBootApplication:组合注解,包含以下注解:
    • @Configuration:标记为配置类。
    • @EnableAutoConfiguration:启用自动配置。
    • @ComponentScan:扫描组件。
  • main方法:应用的入口点。

示例

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

7. Spring Boot的Actuator

问题:什么是Spring Boot的Actuator?

答案

  • Actuator:Spring Boot提供监控和管理应用的端点。
  • 功能
    • 健康检查:/actuator/health
    • 应用信息:/actuator/info
    • 环境信息:/actuator/env
    • 日志配置:/actuator/loggers
    • 线程转储:/actuator/threaddump
    • 度量指标:/actuator/metrics

8. Spring Boot的日志

问题:Spring Boot如何配置日志?

答案

properties
# application.properties
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.file.name=app.log
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
yaml
# application.yml
logging:
  level:
    root: INFO
    com.example: DEBUG
  file:
    name: app.log
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

9. Spring Boot的数据源配置

问题:如何配置Spring Boot的数据源?

答案

properties
# application.properties
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

# HikariCP连接池配置
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000

10. Spring Boot的JPA配置

问题:如何配置Spring Boot的JPA?

答案

properties
# application.properties
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect

11. Spring Boot的事务管理

问题:Spring Boot如何配置事务管理?

答案

java
// 启用事务管理
@SpringBootApplication
@EnableTransactionManagement
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 使用事务
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Transactional
    public void createUser(User user) {
        userRepository.save(user);
    }
}

12. Spring Boot的RESTful API

问题:如何使用Spring Boot创建RESTful API?

答案

java
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping
    public List<User> getUsers() {
        return userService.findAll();
    }
    
    @GetMapping("/{id}")
    public User getUserById(@PathVariable int id) {
        return userService.findById(id);
    }
    
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
    
    @PutMapping("/{id}")
    public User updateUser(@PathVariable int id, @RequestBody User user) {
        user.setId(id);
        return userService.update(user);
    }
    
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable int id) {
        userService.delete(id);
    }
}

13. Spring Boot的异常处理

问题:Spring Boot如何处理异常?

答案

java
// 全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Map<String, Object> handleException(Exception e) {
        Map<String, Object> result = new HashMap<>();
        result.put("error", e.getMessage());
        return result;
    }
}

// 自定义异常
public class BusinessException extends RuntimeException {
    private int code;
    
    public BusinessException(int code, String message) {
        super(message);
        this.code = code;
    }
    
    public int getCode() {
        return code;
    }
}

// 处理自定义异常
@ExceptionHandler(BusinessException.class)
@ResponseBody
public Map<String, Object> handleBusinessException(BusinessException e) {
    Map<String, Object> result = new HashMap<>();
    result.put("code", e.getCode());
    result.put("message", e.getMessage());
    return result;
}

14. Spring Boot的参数验证

问题:Spring Boot如何验证请求参数?

答案

java
// 实体类
public class User {
    @NotNull
    @Size(min = 2, max = 30)
    private String name;
    
    @NotNull
    @Email
    private String email;
    
    @NotNull
    @Min(18)
    private int age;
    
    // getters and setters
}

// 控制器方法
@RestController
@RequestMapping("/api/users")
public class UserController {
    @PostMapping
    public User createUser(@Valid @RequestBody User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new BusinessException(400, "参数验证失败");
        }
        return userService.save(user);
    }
}

15. Spring Boot的文件上传

问题:Spring Boot如何处理文件上传?

答案

java
// 配置文件上传
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

// 控制器方法
@RestController
@RequestMapping("/api/files")
public class FileController {
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file) {
        if (!file.isEmpty()) {
            try {
                byte[] bytes = file.getBytes();
                Path path = Paths.get("uploads/" + file.getOriginalFilename());
                Files.write(path, bytes);
                return "上传成功";
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "上传失败";
    }
}

16. Spring Boot的异步处理

问题:Spring Boot如何实现异步处理?

答案

java
// 启用异步处理
@SpringBootApplication
@EnableAsync
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 异步方法
@Service
public class AsyncService {
    @Async
    public CompletableFuture<String> asyncMethod() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return CompletableFuture.completedFuture("Async result");
    }
}

// 控制器方法
@RestController
@RequestMapping("/api/async")
public class AsyncController {
    @Autowired
    private AsyncService asyncService;
    
    @GetMapping
    public CompletableFuture<String> async() {
        return asyncService.asyncMethod();
    }
}

17. Spring Boot的缓存

问题:Spring Boot如何实现缓存?

答案

java
// 启用缓存
@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 配置缓存
@Configuration
public class CacheConfig {
    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("users")));
        return cacheManager;
    }
}

// 缓存方法
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    @Cacheable("users")
    public User findById(int id) {
        return userRepository.findById(id);
    }
    
    @CachePut("users")
    public User update(User user) {
        return userRepository.save(user);
    }
    
    @CacheEvict("users")
    public void delete(int id) {
        userRepository.deleteById(id);
    }
}

18. Spring Boot的定时任务

问题:Spring Boot如何实现定时任务?

答案

java
// 启用定时任务
@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 定时任务
@Component
public class ScheduledTask {
    @Scheduled(cron = "0 0 0 * * ?")
    public void dailyTask() {
        System.out.println("每天执行一次");
    }
    
    @Scheduled(fixedRate = 5000)
    public void fixedRateTask() {
        System.out.println("每5秒执行一次");
    }
    
    @Scheduled(fixedDelay = 5000)
    public void fixedDelayTask() {
        System.out.println("上次执行完成后5秒执行一次");
    }
}

19. Spring Boot的测试

问题:Spring Boot如何进行测试?

答案

java
// 单元测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
    @Autowired
    private UserService userService;
    
    @Test
    public void testFindById() {
        User user = userService.findById(1);
        assertNotNull(user);
        assertEquals("John", user.getName());
    }
}

// Web测试
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class UserControllerTest {
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    public void testGetUsers() throws Exception {
        mockMvc.perform(get("/api/users"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$[0].name").value("John"));
    }
}

20. Spring Boot的打包和部署

问题:Spring Boot如何打包和部署?

答案

bash
# 打包为JAR
mvn clean package

# 运行JAR
java -jar target/myapp.jar

# 指定配置文件
java -jar target/myapp.jar --spring.profiles.active=prod

# 指定端口
java -jar target/myapp.jar --server.port=8081

21. Spring Boot的监控

问题:Spring Boot如何监控应用?

答案

  • Actuator:提供监控端点。
  • Admin:Spring Boot Admin提供可视化的监控界面。
  • Prometheus:集成Prometheus进行监控。
  • Grafana:使用Grafana展示监控数据。

22. Spring Boot的微服务

问题:Spring Boot如何构建微服务?

答案

  • Spring Cloud:基于Spring Boot的微服务框架。
  • Eureka:服务注册与发现。
  • Ribbon:客户端负载均衡。
  • Feign:声明式HTTP客户端。
  • Hystrix:熔断器。
  • Zuul:API网关。
  • Config:配置中心。

23. Spring Boot的Docker部署

问题:Spring Boot如何部署到Docker?

答案

dockerfile
# Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
COPY target/myapp.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
bash
# 构建Docker镜像
docker build -t myapp .

# 运行Docker容器
docker run -p 8080:8080 myapp

24. Spring Boot的Kubernetes部署

问题:Spring Boot如何部署到Kubernetes?

答案

yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  ports:
  - port: 80
    targetPort: 8080
bash
# 部署到Kubernetes
kubectl apply -f deployment.yaml

25. Spring Boot的最佳实践

问题:Spring Boot的最佳实践有哪些?

答案

  • 使用起步依赖简化依赖管理。
  • 使用自动配置减少配置。
  • 使用Profile区分不同环境。
  • 使用Actuator监控应用。
  • 使用缓存提高性能。
  • 使用异步处理提高并发。
  • 使用异常处理统一错误响应。
  • 使用参数验证保证数据正确性。
  • 使用日志记录应用状态。
  • 使用测试保证代码质量。