You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Spring Boot Starter最佳实践问询:能否定义@Controller等组件?

Spring Boot Starter Best Practices: Controllers/Services and Global Exception Handling

Great question! Moving your shared Spring Boot patterns (like database event logging, MDC-enhanced exception handling) into a custom Starter is exactly the right call—that’s precisely what Starters are built for: encapsulating reusable, opinionated cross-cutting logic across multiple applications. Let’s break down your core questions with practical guidance:

Can I define @Controller or @Service in a Starter?

Yes, but only for generic, non-business-specific components—Starters should never contain application-specific logic. Here’s how to do it properly:

  • @Service is ideal for shared utilities: For example, a DatabaseLoggingService that handles persisting events with MDC context is perfect. To give consuming apps flexibility, add @ConditionalOnMissingBean so they can override your implementation if needed:
    @Service
    @ConditionalOnMissingBean
    public class DefaultDatabaseLoggingService implements DatabaseLoggingService {
        // Implementation that writes logs to DB with MDC attributes
    }
    
  • Limit @Controllers to universal endpoints: Only add Controllers if they serve cross-app needs (like a shared health check or log query endpoint). Never include Controllers tied to specific business domains—those belong in your individual applications.
  • Control component scanning: If you use @ComponentScan in your Starter, explicitly restrict it to your Starter’s package (e.g., @ComponentScan(basePackages = "com.yourorg.shared.starter")) to avoid accidentally picking up beans from consuming apps.

Can I define global exception handling logic?

Absolutely—this is one of the top use cases for a Starter! Global exception handling with @ControllerAdvice is a classic cross-cutting concern that belongs in shared infrastructure. Here’s how to implement it well:

  • Build a reusable @ControllerAdvice class: Add your universal exception handling logic here—catch common exceptions, inject MDC context, log errors to the database, and return consistent error responses. Example:
    @ControllerAdvice
    public class GlobalExceptionHandler {
        private final DatabaseLoggingService loggingService;
    
        public GlobalExceptionHandler(DatabaseLoggingService loggingService) {
            this.loggingService = loggingService;
        }
    
        @ExceptionHandler(RuntimeException.class)
        public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException ex) {
            // Generate and attach error ID to MDC
            String errorId = UUID.randomUUID().toString();
            MDC.put("errorId", errorId);
            // Log error to database with MDC context
            loggingService.logException(ex, MDC.getCopyOfContextMap());
            // Return standardized error response
            ErrorResponse response = new ErrorResponse(errorId, "An unexpected error occurred");
            return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
  • Allow customization: Let consuming apps extend or override your logic:
    • Mark key handler methods as protected so apps can override them
    • Use @Order to set a default priority (e.g., @Order(100))—apps can define their own @ControllerAdvice with a higher priority (lower number) to take precedence
    • Add configuration properties (via @ConfigurationProperties) to let users toggle features like database logging or adjust error response formats

Bonus Starter Best Practices

To make your Starter robust and user-friendly:

  • Use auto-configuration: Wrap your beans in an @Configuration class with conditions like @ConditionalOnClass (only load if Spring Web is present) or @ConditionalOnProperty (let users enable/disable features via application.properties)
  • Minimize mandatory dependencies: Mark non-critical libraries as optional in your build file so consuming apps don’t pull in unused code
  • Document thoroughly: Add clear Javadocs to your classes, and include a README explaining how to use the Starter, override defaults, and configure properties

内容的提问来源于stack exchange,提问作者Barium Scoorge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:28:28