手动使用new实例化Spring Bean会新建实例还是获取Spring托管实例?
结论
直接使用new操作符实例化标注了@Service等Spring组件注解的类,只会创建全新的、不受Spring容器管理的独立实例,不会返回Spring容器中已托管的实例。
核心原因
- Spring的
@Service、@Component等注解本身不会修改类的原生实例化逻辑,只有被Spring组件扫描逻辑捕获、由Spring容器主动创建的实例,才会被纳入容器托管,获得依赖注入、AOP增强、生命周期管理等Spring提供的能力。 - 手动
new出来的ValidationService实例对Spring容器完全不可见:如果该类内部有通过Spring注入的依赖(比如@Autowired标注的其他Bean),手动new出的实例中这些依赖全部为null,运行时大概率触发空指针异常。
重构建议
如果需要获取容器托管的ValidationService实例,优先使用Spring标准注入方式:
- 构造器注入(Spring官方推荐方式)
// 需保证使用该Bean的类本身也是Spring托管的组件,比如标注@Service/@Component等 @Service public class BizService { private final ValidationService validationService; // Spring 4.3+版本下,若类仅有一个构造方法,无需额外添加@Autowired注解 public BizService(ValidationService validationService) { this.validationService = validationService; } }
- 非Spring托管类中获取Bean的方式
如果需要在不受Spring管理的类中获取实例,可以通过实现ApplicationContextAware的工具类从容器中拉取,避免手动new:
@Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { context = applicationContext; } public static <T> T getBean(Class<T> beanClass) { return context.getBean(beanClass); } } // 调用示例 ValidationService validationService = SpringContextHolder.getBean(ValidationService.class);
内容的提问来源于stack exchange,提问作者Melad Basilius
相关产品推荐
相关产品推荐

