new对象后内部@Autowired注入的bean为null的最佳解决实践是什么
问题核心原因
@Autowired 注解的依赖注入功能仅对Spring容器托管的Bean生效,你通过new MyApp()手动实例化的对象不受Spring容器管理,因此Spring不会自动装配其内部标注了@Autowired的属性,所以carIF为null是正常现象。
可行解决方案
你不需要将整条调用链路的类都注册为Spring Bean,可以根据业务场景选择以下方案:
方案1:手动从Spring上下文获取Bean注入到手动创建的对象中
封装一个Spring上下文工具类,直接从容器中取出CarIF的实例,赋值给手动new出来的MyApp对象即可,侵入性极低。
首先实现Spring上下文工具类:import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } // 按类型获取Bean public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } }实例化
MyApp的时候手动完成属性注入:MyApp app = new MyApp(); app.setCarIF(SpringContextUtil.getBean(CarIF.class));方案2:使用@Configurable注解配合AspectJ织入
如果你有大量手动new的类都需要自动注入Spring依赖,可以给MyApp类添加@Configurable注解,开启AspectJ编译时或加载时织入,就算对象是手动创建的,Spring也会自动注入其内部依赖。
操作步骤:- 给
MyApp类添加@Configurable注解 - 在Spring启动类添加
@EnableSpringConfigured注解开启配置 - 引入AspectJ相关依赖并配置织入规则
该方案适合非容器托管类注入依赖需求较多的场景,但需要额外配置织入逻辑,复杂度高于方案1。
- 给
方案3:调整代码结构,将依赖作为构造参数传入
移除MyApp类的@Autowired注解,把需要的依赖作为构造方法参数传入,完全脱离Spring注解依赖:public class MyApp { private final CarIF carIF; // 构造方法显式传入依赖 public MyApp(CarIF carIF) { this.carIF = carIF; } }实例化的时候直接传参:
MyApp app = new MyApp(SpringContextUtil.getBean(CarIF.class));该方案代码无Spring侵入性,依赖关系清晰,适合调用链路层级不深的场景。
内容的提问来源于stack exchange,提问作者FullStackDeveloper
相关产品推荐
相关产品推荐

