Spring Boot 配置参考

Spring Boot 常用配置、注解、代码片段速查,支持搜索和一键复制

服务器配置(5)

端口配置

修改默认端口 8080

# application.yml
server:
  port: 9090

上下文路径

设置应用根路径前缀

server:
  servlet:
    context-path: /api

HTTPS 配置

启用 SSL/HTTPS

server:
  port: 8443
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: changeit
    key-store-type: PKCS12

Gzip 压缩

启用响应压缩减少传输量

server:
  compression:
    enabled: true
    mime-types: application/json,text/html,text/css
    min-response-size: 1024

多环境配置

根据环境加载不同配置

# application.yml 中指定激活环境
spring:
  profiles:
    active: dev

# 创建对应文件:
# application-dev.yml   (开发)
# application-prod.yml  (生产)
# application-test.yml  (测试)

数据库配置(4)

MySQL 数据源

配置 MySQL 数据库连接

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8mb4
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

HikariCP 连接池

配置数据库连接池参数

spring:
  datasource:
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      idle-timeout: 600000
      connection-timeout: 30000
      max-lifetime: 1800000

PostgreSQL 数据源

配置 PostgreSQL 连接

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: postgres
    password: 123456
    driver-class-name: org.postgresql.Driver

Redis 配置

配置 Redis 连接

spring:
  data:
    redis:
      host: localhost
      port: 6379
      password: your_password
      database: 0
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0

JPA / MyBatis(3)

JPA 配置

Spring Data JPA 基本配置

spring:
  jpa:
    hibernate:
      ddl-auto: update  # none/create/update/validate
    show-sql: true
    properties:
      hibernate:
        format_sql: true
        dialect: org.hibernate.dialect.MySQL8Dialect

MyBatis 配置

MyBatis 基本配置

mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.entity
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

MyBatis-Plus 配置

MyBatis-Plus 增强配置

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0
  configuration:
    map-underscore-to-camel-case: true

日志配置(2)

日志级别

设置日志输出级别

logging:
  level:
    root: INFO
    com.example: DEBUG
    org.springframework.web: WARN
    org.hibernate.SQL: DEBUG

日志文件

将日志输出到文件

logging:
  file:
    name: logs/app.log
    max-size: 100MB
    max-history: 30
  pattern:
    file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

安全配置(4)

Spring Security 基本配置

配置认证和授权

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .sessionManagement(s -> s
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            );
        return http.build();
    }
}

CORS 跨域配置

配置跨域访问

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
            .allowedOrigins("http://localhost:3000")
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowedHeaders("*")
            .allowCredentials(true)
            .maxAge(3600);
    }
}

JWT 过滤器

自定义 JWT 认证过滤器

public class JwtAuthFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res,
                                    FilterChain chain) throws ServletException, IOException {
        String token = extractToken(req);
        if (token != null && jwtUtil.validateToken(token)) {
            Authentication auth = jwtUtil.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(auth);
        }
        chain.doFilter(req, res);
    }
}

方法级安全

使用 @PreAuthorize 等方法级权限控制

@Configuration
@EnableMethodSecurity
public class MethodSecurityConfig { }

@Service
public class UserService {
    @PreAuthorize("hasRole('ADMIN')")
    public void deleteUser(Long id) { }

    @PreAuthorize("#id == authentication.principal.id")
    public User getProfile(Long id) { }
}

缓存配置(2)

启用缓存

开启 Spring Cache

# application.yml
spring:
  cache:
    type: redis
    redis:
      time-to-live: 3600000  # 1小时

# 主类添加注解
@SpringBootApplication
@EnableCaching
public class Application { }

缓存注解

常用缓存注解

@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User findById(Long id) { ... }

    @CachePut(value = "users", key = "#user.id")
    public User update(User user) { ... }

    @CacheEvict(value = "users", key = "#id")
    public void delete(Long id) { ... }

    @CacheEvict(value = "users", allEntries = true)
    public void clearAll() { ... }
}

常用注解(4)

Controller 注解

Web 层常用注解

@RestController
@RequestMapping("/api/users")
public class UserController {

    @GetMapping            // GET /api/users
    @GetMapping("/{id}")   // GET /api/users/1
    @PostMapping           // POST /api/users
    @PutMapping("/{id}")   // PUT /api/users/1
    @DeleteMapping("/{id}")// DELETE /api/users/1
}

参数绑定注解

请求参数绑定

// 路径参数
@GetMapping("/{id}")
public User get(@PathVariable Long id)

// 查询参数 ?name=xxx
@GetMapping
public List<User> search(@RequestParam String name)

// 请求体
@PostMapping
public User create(@RequestBody @Valid UserDTO dto)

// 请求头
@GetMapping
public void get(@RequestHeader("Authorization") String token)

校验注解

参数校验

public class UserDTO {
    @NotBlank(message = "用户名不能为空")
    private String username;

    @Email(message = "邮箱格式不正确")
    private String email;

    @Size(min = 6, max = 20, message = "密码长度6-20位")
    private String password;

    @Min(0) @Max(150)
    private Integer age;
}

事务注解

声明式事务管理

@Service
public class OrderService {

    @Transactional
    public void createOrder(Order order) {
        // 事务内操作
    }

    @Transactional(rollbackFor = Exception.class)
    public void process() {
        // 遇到任何异常都回滚
    }

    @Transactional(readOnly = true)
    public List<Order> list() {
        // 只读事务,优化性能
    }
}

异常处理(3)

@ExceptionHandler

Controller 内处理特定异常

@RestController
public class UserController {

    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleNotFound(ResourceNotFoundException e) {
        return ResponseEntity.status(404).body(e.getMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidation(MethodArgumentNotValidException e) {
        Map<String, String> errors = new HashMap<>();
        e.getBindingResult().getFieldErrors().forEach(err ->
            errors.put(err.getField(), err.getDefaultMessage()));
        return ResponseEntity.badRequest().body(errors);
    }
}

@ControllerAdvice

全局异常处理器

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleAll(Exception e) {
        ErrorResponse err = new ErrorResponse(500, e.getMessage());
        return ResponseEntity.status(500).body(err);
    }

    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<ErrorResponse> handleBusiness(BusinessException e) {
        return ResponseEntity.badRequest().body(new ErrorResponse(400, e.getMessage()));
    }
}

ResponseEntity 错误响应

统一构造错误响应体

public class ErrorResponse {
    private int code;
    private String message;
    private long timestamp;
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handle(Exception e) {
    return ResponseEntity
        .status(HttpStatus.INTERNAL_SERVER_ERROR)
        .body(new ErrorResponse(500, e.getMessage(), System.currentTimeMillis()));
}

AOP 切面(4)

@Aspect 基础

声明切面类

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() { }
}

@Before @After

前置与后置通知

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void before(JoinPoint jp) {
        log.info("调用: " + jp.getSignature().getName());
    }

    @After("execution(* com.example.service.*.*(..))")
    public void after(JoinPoint jp) {
        log.info("完成: " + jp.getSignature().getName());
    }
}

@Around

环绕通知,可控制方法执行

@Around("execution(* com.example.service.*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.currentTimeMillis();
    try {
        return pjp.proceed();
    } finally {
        log.info("耗时: " + (System.currentTimeMillis() - start) + "ms");
    }
}

@Pointcut 表达式

常用切点表达式

@Pointcut("execution(* com.example.service.*.*(..))")
private void serviceMethods() { }

@Pointcut("@annotation(com.example.annotation.Log)")
private void logAnnotation() { }

@Pointcut("within(com.example.controller..*)")
private void controllerLayer() { }

@Pointcut("bean(userService)")
private void userServiceBean() { }

异步与调度(3)

@Async 异步方法

方法异步执行

@Service
public class UserService {

    @Async
    public CompletableFuture<User> findUserAsync(Long id) {
        User user = userRepo.findById(id).orElseThrow();
        return CompletableFuture.completedFuture(user);
    }
}

@SpringBootApplication
@EnableAsync
public class Application { }

CompletableFuture

异步编排与组合

@Async
public CompletableFuture<Result> processAsync() {
    return CompletableFuture.supplyAsync(() -> doWork())
        .thenApply(r -> transform(r))
        .exceptionally(ex -> handleError(ex));
}

定时任务 @Scheduled

定时执行任务

@SpringBootApplication
@EnableScheduling
public class Application { }

@Component
public class MyTask {

    @Scheduled(fixedRate = 60000)
    public void task1() { }

    @Scheduled(cron = "0 0 2 * * ?")
    public void task2() { }

    @Scheduled(fixedDelay = 5000, initialDelay = 1000)
    public void task3() { }
}

测试(4)

@SpringBootTest

集成测试加载完整上下文

@SpringBootTest
class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    void testFindUser() {
        User user = userService.findById(1L);
        assertNotNull(user);
    }
}

@WebMvcTest

Web 层单元测试

@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void testGetUser() throws Exception {
        when(userService.findById(1L)).thenReturn(new User());
        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk());
    }
}

@MockBean

注入 Mock 对象替换 Bean

@SpringBootTest
class OrderServiceTest {

    @Autowired
    private OrderService orderService;

    @MockBean
    private UserService userService;

    @MockBean
    private OrderRepository orderRepository;

    @Test
    void testCreateOrder() {
        when(userService.getCurrent()).thenReturn(new User());
        orderService.create(new Order());
        verify(orderRepository).save(any());
    }
}

MockMvc 请求模拟

模拟 HTTP 请求并断言

mockMvc.perform(
    post("/api/users")
        .contentType(MediaType.APPLICATION_JSON)
        .content("{\"name\":\"test\"}")
)
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("test"));

Actuator 监控(1)

启用 Actuator

添加健康检查和监控端点

# pom.xml 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: always

文件上传(2)

文件上传配置

配置文件上传大小限制

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 50MB

文件上传接口

编写文件上传 Controller

@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file) {
    String filename = file.getOriginalFilename();
    String path = "/uploads/" + UUID.randomUUID() + "-" + filename;
    file.transferTo(new File(path));
    return path;
}

其他配置(10)

JSON 日期格式

配置 JSON 序列化日期格式

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: Asia/Shanghai
    default-property-inclusion: non_null

国际化

配置多语言消息

spring:
  messages:
    basename: i18n/messages
    encoding: UTF-8

拦截器 HandlerInterceptor

请求前后拦截处理

public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
        if (req.getHeader("Authorization") == null) {
            res.setStatus(401);
            return false;
        }
        return true;
    }
}

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor())
            .addPathPatterns("/api/**")
            .excludePathPatterns("/api/login");
    }
}

@ConfigurationProperties

配置属性绑定到 Bean

@ConfigurationProperties(prefix = "app")
@Component
public class AppProperties {
    private String name;
    private int maxSize = 100;
    private List<String> allowedHosts;
}

# application.yml
app:
  name: myapp
  max-size: 200
  allowed-hosts: localhost,127.0.0.1

@Value 注入

注入单个配置值

@Component
public class MyService {
    @Value("${app.name}")
    private String appName;

    @Value("${server.port:8080}")
    private int port;

    @Value("${app.features:true}")
    private boolean featureEnabled;
}

Swagger / OpenAPI

springdoc-openapi 配置

# pom.xml
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version>
</dependency>

# application.yml
springdoc:
  api-docs:
    path: /v3/api-docs
  swagger-ui:
    path: /swagger-ui.html

Maven 常用

spring-boot-maven-plugin 与 profiles

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

# 打包: mvn clean package
# 指定 profile: mvn spring-boot:run -Dspring-boot.run.profiles=dev
# 跳过测试: mvn package -DskipTests

WebSocket 配置

SockJS + STOMP 消息订阅

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();
    }
}

RabbitMQ 配置

消息队列基本配置

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
        acknowledge-mode: auto
        prefetch: 1

@RabbitListener(queues = "my.queue")
public void handle(Message msg) { }

Kafka 配置

Kafka 生产者与消费者

spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: my-group
      auto-offset-reset: earliest
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer

@KafkaListener(topics = "my-topic")
public void listen(String message) { }

相关工具