如何将反射创建的对象纳入Spring上下文以实现Autowired注入?
解决手动创建对象的Spring依赖注入失效问题
问题场景
主应用引入工具应用的Jar包,工具应用通过反射创建主应用中类A的实例,但类A中用@Autowired修饰的Calculator变量始终为null——原因很明确:手动new出来的对象不在Spring上下文管理范围内,Spring不会自动为其注入依赖。
解决方案
下面提供两种可行的处理方式,根据实际场景选择:
方式一:直接从Spring上下文获取Bean(推荐)
如果类A本身可以被Spring管理(比如给类A加上@Component注解),直接从Spring上下文获取实例即可,此时依赖已经自动注入完成:
- 主应用中添加Spring上下文持有类,方便外部获取:
package m.main.application; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class ApplicationContextHolder implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) { context = applicationContext; } public static ApplicationContext getContext() { return context; } }
- 修改工具应用的
Util类,从上下文获取类A实例:
class Util { public void createObjectAndRun() { // 获取Spring上下文 ApplicationContext context = ApplicationContextHolder.getContext(); // 直接获取已完成依赖注入的Bean实例 Action newObject = context.getBean(A.class); newObject.execute(); } }
方式二:手动触发Spring依赖注入
如果类A无法被声明为Spring Bean,可手动创建实例后,调用Spring的API为其注入依赖:
修改工具应用的Util类:
class Util { public void createObjectAndRun() { try { Class<?> clazz = Class.forName("m.main.application.A"); Action newObject = (Action) clazz.getConstructor().newInstance(); // 获取Spring上下文,触发依赖注入 ApplicationContext context = ApplicationContextHolder.getContext(); context.getAutowireCapableBeanFactory().autowireBean(newObject); newObject.execute(); } catch (Exception e) { e.printStackTrace(); } } }
注意事项
ApplicationContextHolder必须被Spring扫描到,确保它能被实例化并持有上下文。Calculator类必须是Spring管理的Bean(比如添加@Component/@Service注解),否则Spring找不到可注入的实例。- 如果工具应用需要直接注入
ApplicationContext,可在Util类上添加@Component,并确保主应用的@ComponentScan包含工具应用的包路径。
内容的提问来源于stack exchange,提问作者Nish
相关产品推荐
相关产品推荐

