王旭阳个人博客

WXY

SpringBoot 常用扩展接口

2025-03-14

2025-03-14-rmawtkso.webp

在Spring Boot应用开发中,框架通过丰富的扩展点设计,为开发者提供了灵活的应用定制能力。这些扩展接口不仅能够无缝融入应用生命周期的各个阶段(如启动、运行、关闭),还能针对业务场景实现深度定制,显著提升代码的可维护性和可扩展性。无论是增强核心功能、统一处理全局逻辑,还是优化特定场景下的性能,Spring Boot的扩展机制都能以优雅的方式解决问题,避免对框架源码的侵入性修改。以下是一些核心扩展接口及其分类,它们将帮助开发者更好地驾驭Spring Boot的定制化能力:

一、应用启动阶段

1. ApplicationContextInitializer

  • 用途:在 ApplicationContext 初始化前执行自定义逻辑(如设置环境变量)。

  • 示例

    public class MyInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        @Override
        public void initialize(ConfigurableApplicationContext context) {
            // 自定义初始化逻辑
        }
    }
    
  • 注册方式:在 META-INF/spring.factories 中添加:

    org.springframework.context.ApplicationContextInitializer=com.example.MyInitializer

2. CommandLineRunner

  • 用途:在应用启动后执行命令行参数相关的任务。

  • 示例

    @Component
    public class MyRunner implements CommandLineRunner {
        @Override
        public void run(String... args) {
            // 启动后执行的任务
        }
    }

3. ApplicationRunner

  • 用途:与 CommandLineRunner 类似,但参数封装为 ApplicationArguments

  • 示例

    @Component
    public class MyAppRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) {
            // 处理参数
        }
    }

二、Bean 生命周期

1. BeanPostProcessor

  • 用途:在 Bean 初始化前后插入自定义逻辑。

  • 示例

    @Component
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            // Bean 初始化前的逻辑
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            // Bean 初始化后的逻辑
            return bean;
        }
    }
    

2. BeanFactoryPostProcessor

  • 用途:在 Bean 定义加载后、实例化前修改 Bean 的定义。

  • 示例

    
    @Component
    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            // 修改 Bean 定义
        }
    }
    

SmartInitializingSingleton

  • 用途:在所有单例 Bean 初始化完成后执行逻辑。

  • 示例

    @Component
    public class MySmartInitializer implements SmartInitializingSingleton {
        @Override
        public void afterSingletonsInstantiated() {
            // 单例 Bean 初始化完成后执行
        }
    }
    
    

三、事件监听

1. ApplicationListener

  • 用途:监听 Spring 事件(如应用启动事件)。

  • 示例

    @Component
    public class MyEventListener implements ApplicationListener<ApplicationStartedEvent> {
        @Override
        public void onApplicationEvent(ApplicationStartedEvent event) {
            // 处理应用启动事件
        }
    }
    

2. 自定义事件

  • 发布事件

    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    public void publishEvent() {
        eventPublisher.publishEvent(new MyCustomEvent("Custom Event Data"));
    }
    
  • 监听事件

    @Component
    public class MyCustomEventListener implements ApplicationListener<MyCustomEvent> {
        @Override
        public void onApplicationEvent(MyCustomEvent event) {
            // 处理自定义事件
        }
    }
    

四、Web 扩展

1. WebMvcConfigurer

  • 用途:自定义 Spring MVC 配置(如拦截器、跨域设置)。

  • 示例

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MyInterceptor());
        }
    }
    

2. ServletContextInitializer

  • 用途:在 Servlet 容器初始化时注册 Servlet、Filter 或 Listener。

  • 示例

    @Bean
    public ServletContextInitializer servletContextInitializer() {
        return servletContext -> {
            ServletRegistration.Dynamic servlet = servletContext.addServlet("myServlet", MyServlet.class);
            servlet.addMapping("/my-servlet/*");
        };
    }
    
    

3. WebFluxConfigurer

  • 用途:在响应式 Web 应用(WebFlux)中自定义配置,如路由、编解码器、CORS 等。

  • 示例

    
    @Configuration
    public class WebFluxConfig implements WebFluxConfigurer {
        
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            // 配置CORS(跨域资源共享)
            registry.addMapping("/api/**") // 对API路径应用CORS配置
                    .allowedOrigins("https://example.com") // 允许的来源
                    .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
                    .allowCredentials(true) // 允许发送身份凭证
                    .maxAge(3600); // 预检请求结果缓存时间(秒)
            
            log.info("响应式应用CORS配置已应用");
        }
        
        @Override
        public void configureViewResolvers(ViewResolverRegistry registry) {
            // 配置视图解析器
            registry.freeMarker();
        }
        
        @Override
        public void addFormatters(FormatterRegistry registry) {
            // 添加自定义格式转换器
            registry.addConverter(new MonoConverter());
        }
    }

4. HandlerMethodArgumentResolver

  • 用途:自定义控制器方法参数的解析逻辑(如从请求头、Cookie 中提取参数)。

  • 示例

    @Component
    public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {
        
        @Autowired
        private UserService userService;
        
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            // 判断方法参数是否支持此解析器
            // 这里检查参数是否有@CurrentUser注解且类型为User
            return parameter.hasParameterAnnotation(CurrentUser.class) 
                   && parameter.getParameterType().equals(User.class);
        }
        
        @Override
        public Object resolveArgument(
                MethodParameter parameter, 
                ModelAndViewContainer mavContainer,
                NativeWebRequest webRequest, 
                WebDataBinderFactory binderFactory) throws Exception {
            
            // 从请求中解析出参数值
            // 例如,从HTTP请求头或会话中获取用户ID,然后加载用户对象
            String authHeader = webRequest.getHeader("Authorization");
            if (authHeader != null && authHeader.startsWith("Bearer ")) {
                // 从Authorization头提取token
                String token = authHeader.substring(7);
                // 使用token查找用户
                return userService.findUserByToken(token);
            }
            
            // 如果找不到用户,可以返回null或抛出异常
            return null;
        }
    }
    

  • 注册方式:在 WebMvcConfigurerWebFluxConfigurer 中添加:

    // 注册参数解析器
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        
        @Autowired
        private CurrentUserArgumentResolver currentUserArgumentResolver;
        
        @Override
        public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
            resolvers.add(currentUserArgumentResolver);
        }
    }

五、条件化配置

1. Condition

  • 用途:根据条件决定是否加载 Bean 或配置类。

  • 示例

    public class MyCondition implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return context.getEnvironment().containsProperty("enable.feature");
        }
    }
    
    @Configuration
    @Conditional(MyCondition.class)
    public class MyFeatureConfig {
        // 条件满足时加载的配置
    }
    

2. @ConditionalOnProperty

  • 用途:根据配置文件属性决定是否生效。

  • 示例

    @Bean
    @ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
    public CacheManager cacheManager() {
        return new EhCacheManager();
    }
    

六、健康检查与监控

1. HealthIndicator

  • 用途:自定义健康检查端点。

  • 示例

    @Component
    public class MyHealthIndicator implements HealthIndicator {
        @Override
        public Health health() {
            // 检查自定义组件的健康状态
            return Health.up().withDetail("detail", "OK").build();
        }
    }
    
    

2. Endpoint

  • 用途:自定义 Actuator 端点。

  • 示例

    @Component
    @Endpoint(id = "my-endpoint")
    public class MyCustomEndpoint {
        @ReadOperation
        public String getInfo() {
            return "Custom Endpoint Data";
        }
    }
    

七、其他扩展点

1. EnvironmentPostProcessor

  • 用途:在环境变量加载后修改配置。

  • 示例

    public class MyEnvPostProcessor implements EnvironmentPostProcessor {
        @Override
        public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
            // 修改环境变量
        }
    }
    

2. FailureAnalyzer

  • 用途:自定义应用启动失败时的错误分析。

  • 示例

    public class MyFailureAnalyzer extends AbstractFailureAnalyzer<MyException> {
        @Override
        protected FailureAnalysis analyze(Throwable rootFailure, MyException cause) {
            return new FailureAnalysis("Description", "Action", cause);
        }
    }

3. ErrorAttributes

  • 用途:定制全局错误响应信息(如 HTTP 错误码、错误消息格式)。

  • 示例

    @Component
    public class CustomErrorAttributes extends DefaultErrorAttributes {
        
        @Override
        public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
            // 获取默认的错误属性
            Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
            
            // 添加自定义错误属性
            errorAttributes.put("appName", "MyAwesomeApp");
            errorAttributes.put("timestamp", LocalDateTime.now().toString());
            
            // 移除不想暴露的错误信息
            errorAttributes.remove("trace");
            
            // 获取原始异常以便添加更多上下文
            Throwable error = getError(webRequest);
            if (error instanceof BusinessException) {
                BusinessException businessEx = (BusinessException) error;
                errorAttributes.put("errorCode", businessEx.getErrorCode());
                errorAttributes.put("domain", businessEx.getDomain());
            }
            
            return errorAttributes;
        }
    }
     

八、执行顺序与优先级

  • @Order 注解:指定 Bean 的加载顺序(值越小优先级越高)。

    @Component
    @Order(1)
    public class HighPriorityBean implements CommandLineRunner {
        // 优先执行
    }
    

通过合理使用这些扩展接口,可以灵活定制 Spring Boot 应用的行为,满足复杂业务场景的需求。