Spring中向ResourceBundle实现类注入Bean时依赖为空问题求助
解决方案:Spring注入ResourceBundle实现类依赖的问题
核心原因是:ResourceBundle.getBundle()是JDK原生方法,它创建的对象不在Spring容器的管理范围内,所以Spring无法自动完成依赖注入。即使加了@Configurable,也需要AspectJ织入的完整配置才能生效,稍不留神就会失效。下面是几种可行的解决方法:
方案一:自定义ResourceBundle.Control,让Spring管理实例
通过自定义Control,让JDK在加载ResourceBundle时从Spring容器获取实例,而非自行创建:
- 将你的ResourceBundle实现类声明为Spring组件:
@Component public class CustomResourceBundle extends ResourceBundle { @Autowired private QuestionnaireCache questionnaireCache; @Autowired private SomeServiceTest someServiceTest; @Override protected Object handleGetObject(String key) { // 此处可直接使用注入的Bean处理业务逻辑 return null; } @Override public Enumeration<String> getKeys() { return null; } }
- 实现自定义的
ResourceBundle.Control,从Spring容器获取实例:
@Component public class SpringResourceBundleControl extends ResourceBundle.Control { private final ApplicationContext applicationContext; @Autowired public SpringResourceBundleControl(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IOException, InstantiationException, IllegalAccessException { // 跳过JDK默认的实例化逻辑,直接从Spring容器取Bean return applicationContext.getBean(CustomResourceBundle.class); } }
- 使用自定义Control获取ResourceBundle:
// 注入自定义Control @Autowired private SpringResourceBundleControl springControl; // 在需要使用Bundle的地方调用 ResourceBundle bundle = ResourceBundle.getBundle("your.bundle.base.name", Locale.getDefault(), springControl);
方案二:直接从Spring容器获取ResourceBundle实现类
如果业务场景允许,完全跳过ResourceBundle.getBundle(),直接注入你的实现类:
@Autowired private CustomResourceBundle customResourceBundle;
这种方式最直接,因为对象全程由Spring管理,依赖注入会自动完成。
方案三:修复@Configurable的配置(不推荐,复杂度高)
如果必须使用JDK原生的getBundle(),需要确保AspectJ织入的完整配置:
- 在Spring配置类上添加
@EnableSpringConfigured,开启Configurable支持 - 在你的ResourceBundle实现类上添加
@Configurable(autowire = Autowire.BY_TYPE),指定自动注入方式 - 引入AspectJ依赖:
aspectjrt和aspectjweaver - 开启织入:
- 编译时织入:在Maven/Gradle中配置AspectJ编译插件,编译阶段处理类文件
- 运行时织入:给JVM添加启动参数
-javaagent:/path/to/aspectjweaver.jar
注意:这种方式对配置要求严格,若Spring上下文未完全初始化就调用getBundle(),依然会导致注入失败。
内容的提问来源于stack exchange,提问作者Syed Iftekharuddin
相关产品推荐
相关产品推荐

