Spring Web:ControllerAdvice移至Maven库后异常处理失效问题
首先明确:你的问题和Maven库没有主函数完全无关——Maven库本身不需要主函数,它只是提供可复用的代码和资源,主项目作为Spring Boot应用才需要主函数来启动上下文。真正的问题出在Spring组件扫描、MessageSource Bean的可见性以及资源文件的加载上,下面分点说明解决办法:
1. 确保库中的组件能被主项目扫描到
当你把RestResponseEntityExceptionHandler和MessageSource Bean移到Maven库后,如果主项目的组件扫描范围没有包含库的包路径,这些Bean根本不会被Spring上下文加载,自然会出现找不到消息的错误。
解决方式二选一:
方式一:用@Import导入库的配置类
在库中创建一个配置类,把MessageSourceBean和异常处理器的配置都放在里面:@Configuration public class ExceptionHandlerAutoConfig { @Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("classpath:messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } // 如果父类的@ControllerAdvice没有被扫描到,也可以在这里注册 @Bean public RestResponseEntityExceptionHandler restResponseEntityExceptionHandler() { return new RestResponseEntityExceptionHandler(); } }然后在主项目的启动类或配置类上导入这个配置:
@SpringBootApplication @Import(ExceptionHandlerAutoConfig.class) public class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); } }方式二:扩大主项目的组件扫描范围
修改主项目的@SpringBootApplication注解,把库的包路径加入扫描范围:@SpringBootApplication(scanBasePackages = {"com.your.main.project", "com.your.library.package"}) public class MainApplication { // ... }
2. 验证库中资源文件的打包路径
确保库中的messages_ru.properties确实放在src/main/resources目录下,打包后的Maven库jar包中能找到这个文件。你可以用命令行验证:
jar tf your-library.jar | grep messages_ru.properties
如果输出为空,说明资源文件没有被正确打包,检查库项目的pom.xml是否有资源过滤的配置,比如是否排除了properties文件。
3. 检查@ControllerAdvice的继承与生效
主项目中的继承类存在类名冲突问题:你的类名和Spring自带的ResponseEntityExceptionHandler重名了,这会导致混淆!建议把主项目的类名改成MainRestExceptionHandler之类的独特名称,同时确保父类的@ExceptionHandler方法能被正确继承并生效:
@ControllerAdvice @Primary public class MainRestExceptionHandler extends RestResponseEntityExceptionHandler { }
添加@Primary注解可以确保这个异常处理器是优先被Spring使用的。
4. 处理MessageSource的优先级问题
如果主项目本身也有MessageSource Bean,可能会覆盖库中的Bean。你可以给库中的MessageSource设置更高的优先级:
@Bean @Order(Ordered.HIGHEST_PRECEDENCE) public MessageSource messageSource() { // ... 原配置 }
最后再排查异常细节
你提到的NoSuchMessageException: No message found under code 'description' for locale 'ru_RU',还要确认messages_ru.properties中确实存在description这个key,避免拼写错误或者key缺失。
内容的提问来源于stack exchange,提问作者MrLebovsky

