Cucumber中TypeRegistryConfiguration的@Autowired依赖注入失效求助
问题分析与解决方案
核心问题在于你的TypeRegistryConfiguration没有被Spring容器托管,所以Spring无法为它执行依赖注入——哪怕它所在的包被Spring扫描了也没用,因为Cucumber默认会自行实例化这个类,而不是让Spring来创建它。
而你的步骤类(比如WebServiceSteps)能正常注入CommonContext,是因为当你使用cucumber-spring依赖时,Cucumber会自动把步骤类注册到Spring上下文里,让Spring负责创建和管理这些类的实例,所以依赖注入能正常工作。
解决方案1:将TypeRegistryConfiguration纳入Spring管理(推荐)
这是最符合Spring最佳实践的方式,步骤如下:
- 给
TypeRegistryConfiguration添加@Component注解,让Spring识别它为组件并纳入管理 - 改用构造器注入代替字段注入(字段注入本身就不推荐,且在非Spring托管类里完全失效)
修改后的代码:
package com.funky.steps.typeregistry; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.funky.steps.context.CommonContext; @Component public class TypeRegistryConfiguration implements TypeRegistryConfigurer { private final CommonContext context; // 构造器注入,Spring会自动注入CommonContext实例 @Autowired public TypeRegistryConfiguration(CommonContext context) { this.context = context; } @Override public Locale locale() { return Locale.ENGLISH; } @Override public void configureTypeRegistry(TypeRegistry typeRegistry) { // 现在可以正常使用context里的变量了 registerStuff(typeRegistry); } // 你的其他方法... }
- 确保Cucumber使用Spring管理的实例
由于你已经在使用cucumber-spring,只要你的TypeRegistryConfiguration被Spring扫描到(你说com.funky.steps包已被扫描,其子包typeregistry也会被覆盖),Cucumber的Spring对象工厂就会自动从Spring上下文获取这个类的实例,而不是自行创建。这样依赖注入就能正常生效了。
解决方案2:手动获取Spring上下文(备选)
如果出于某些原因不想把TypeRegistryConfiguration变成Spring组件,可以通过一个上下文持有工具类来手动获取CommonContext:
- 创建Spring上下文持有类:
package com.funky.steps; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext ctx) { applicationContext = ctx; } public static <T> T getBean(Class<T> beanClass) { return applicationContext.getBean(beanClass); } }
- 在
TypeRegistryConfiguration里使用该工具类获取bean:
package com.funky.steps.typeregistry; import com.funky.steps.SpringContextHolder; import com.funky.steps.context.CommonContext; public class TypeRegistryConfiguration implements TypeRegistryConfigurer { private CommonContext context; @Override public void configureTypeRegistry(TypeRegistry typeRegistry) { // 在需要的时候获取CommonContext实例 if (context == null) { context = SpringContextHolder.getBean(CommonContext.class); } // 现在可以使用context里的变量构建请求了 registerStuff(typeRegistry); } // 其他方法... }
这种方式不需要修改TypeRegistryConfiguration的组件状态,但需要确保SpringContextHolder被Spring正确初始化(加了@Component且被扫描到)。
验证要点
- 确认你的Spring配置类(比如带有
@SpringBootApplication或@ComponentScan的类)确实覆盖了com.funky.steps及其子包 - 如果使用解决方案1,确保没有其他地方手动实例化
TypeRegistryConfiguration,否则会绕过Spring的管理
内容的提问来源于stack exchange,提问作者Flyout91
相关产品推荐
相关产品推荐

