Tomcat 10.1.6-1升级后@Service注解失效问题求助
Tomcat 9→10.1升级后Spring @Service注解Bean无法被识别
问题描述
将基于Apache Tomcat 9.0.83的应用升级至10.1.6-1版本,已完成Jakarta命名空间适配,但通过@Service注解注入的Bean无法正常使用:
- 多数XML注册的Bean运行正常,但少量注解类无法被Spring识别
- @Autowired注入的资源为null,调用
applicationContext.getBean("Foo")抛出NoSuchBeanDefinitionException - @PostConstruct等其他注解可正常工作
相关代码
Foo实现类:
import org.springframework.stereotype.Service; @Service("Foo") public class FooImpl extends FooIAbstract { public FooImpl() { } }
已排查操作
- 发现存在两个包含
jakarta.annotation.Resource的jar包,排除jakarta.annotation-api-2.0.0.jar后问题仍未解决 - 尝试添加
@ComponentScan注解无效果 - 在
applicationContext.xml中手动配置Bean定义后,可正常获取该Bean
错误日志
[ERROR] [Mon Apr 08 11:10:35.258 2024] [ajp-nio-127.0.0.1-8009-exec-2|BackupServiceImpl] Error: checking if chosen file name Backup-20244811:10 already exists for the host 127.0.0.1 org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'FOO' available at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:893) ~[spring-beans-6.0.11.jar:6.0.11] at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1318) ~[spring-beans-6.0.11.jar:6.0.11] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) ~[spring-beans-6.0.11.jar:6.0.11] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.11.jar:6.0.11] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1155) ~[spring-context-6.0.11.jar:6.0.11] at com.myCompany.AppContextUtil.getFoo(AppContextUtil.java:48) ~[myCompany-services-impl.jar:?]
依赖配置(pom.xml)
<org.springframework.version>6.0.11</org.springframework.version> <dependencies> <!-- 各类Spring依赖配置略 --> </dependencies>
解决方案
1. 修正Bean名称大小写问题
错误日志提示找不到名为FOO的Bean,但你的@Service注解指定的名称是"Foo",Spring对Bean名称严格区分大小写:
- 要么把
getBean调用改为applicationContext.getBean("Foo")(匹配注解指定的名称) - 要么修改@Service注解为
@Service("FOO"),与调用时的名称保持一致
2. 确保@ComponentScan配置生效
如果添加注解后无效,检查以下几点:
- 确认@ComponentScan的
basePackages覆盖了FooImpl所在的包路径,示例:@Configuration @ComponentScan(basePackages = "com.myCompany.foo") // 替换为实际包路径 public class AppConfig { } - 若用XML配置,需在
applicationContext.xml中添加:<context:component-scan base-package="com.myCompany.foo"/>
3. 检查类加载器与依赖冲突
Tomcat 10.x的类加载机制有变化,需确认:
- 包含@Service类的jar包放在
WEB-INF/lib下,而非Tomcat全局lib目录 - 排查项目依赖与Tomcat自带Jakarta API的冲突,可通过
conf/catalina.properties中的tomcat.util.scan.StandardJarScanFilter.jarsToSkip配置排除冲突jar包
4. 验证Spring上下文加载顺序
- 检查web应用的
web.xml或ServletInitializer,确保Spring上下文配置文件/配置类被正确加载 - 避免多个Spring上下文实例导致注解Bean未加载到当前使用的上下文
内容的提问来源于stack exchange,提问作者RichardFeynman
相关产品推荐
相关产品推荐

