使用new关键字创建类实例时如何实现Spring Bean自动装配
问题根因
通过new First()手动创建的对象一开始并不在Spring容器的托管范围内,@Autowired标记的依赖注入,是Spring在Bean生命周期的属性填充阶段才会执行的操作。你在@Bean方法里刚执行完new操作就立刻调用printFromFirst(),此时Spring还没来得及给这个新建的实例注入依赖,second属性就是默认的null值,自然会触发空指针。
手动new实例场景下的可行实现方式
- 方式1:@Bean方法中手动传入依赖并赋值
直接将需要的依赖作为@Bean方法的形参,Spring会自动将容器中已存在的对应Bean传入,你new完实例后手动给依赖属性赋值即可,修改后的启动类代码如下:
@SpringBootApplication public class SampleApplication { public static void main(String[] args) { SpringApplication.run(SampleApplication.class, args); } @Bean public First first(Second second) { First first = new First(); // 手动为依赖属性赋值 first.setSecond(second); // 此时调用方法不会触发空指针 first.printFromFirst(); return first; } }
注意如果second是私有属性,需要给First类补充对应的setter方法,不推荐直接修改属性访问权限。
- 方式2:借助Bean工厂手动完成实例的依赖注入
如果是在非Spring托管的普通类中手动new实例,可以先获取Spring上下文,通过AutowireCapableBeanFactory完成新建实例的自动装配:
// 从已持有引用的Spring上下文获取Bean工厂 AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); First first = new First(); // 为新建实例自动装配所有@Autowired标记的依赖 beanFactory.autowireBean(first); // 依赖注入完成,可正常调用业务方法 first.printFromFirst();
- 方式3:避免在@Bean方法内提前调用依赖相关方法
Spring拿到@Bean方法返回的实例后,会自动完成该实例的依赖注入。如果你不需要在Bean创建阶段就执行业务逻辑,直接返回新建实例即可,容器完成初始化后再调用方法就不会有空指针问题:
@Bean public First first() { // 仅返回实例,不在方法内调用依赖second的业务方法 return new First(); }
注意:日常业务开发不推荐频繁手动new带有Spring依赖的组件类,这种写法很容易因为遗漏依赖注入触发空指针,常规场景优先使用Spring原生的依赖注入能力获取实例。
内容的提问来源于stack exchange,提问作者Aakash Raj Shakya
相关产品推荐
相关产品推荐

