Spring项目调用context.refresh()后为何报NoSuchBeanDefinitionException异常?
问题原因与解决方案
核心差异:上下文初始化时的配置加载逻辑
你遇到的问题本质是两种AnnotationConfigApplicationContext初始化方式的执行流程不同:
1. 第一种方式(报错场景)的问题
无参构造new AnnotationConfigApplicationContext()创建的是一个空的上下文容器,此时Spring没有任何关于bean定义的来源信息(既不知道要扫描哪个包,也不知道有哪些配置类)。直接调用context.refresh()时,容器没有可加载的bean定义,自然找不到名为database的MySqlCustomerDal实例。
2. 第二种方式(正常场景)的逻辑
new AnnotationConfigApplicationContext("com.springdemo")这个构造器内部会自动完成三个关键步骤:
- 扫描指定包
com.springdemo下所有带有@Component、@Configuration等注解的类 - 将扫描到的
IocConfig(配置类)和MySqlCustomerDal(业务类)注册为bean定义 - 自动触发
refresh()完成上下文初始化,此时容器中已经存在名为database的bean
修复第一种方式的两种方案
如果你想保留无参构造+手动refresh的写法,需要在refresh前告诉Spring bean定义的来源:
方案1:注册配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 注册你的配置类IocConfig,Spring会读取其中的@ComponentScan配置完成扫描 context.register(IocConfig.class); context.refresh(); ICustomerDal customerDal = context.getBean("database", ICustomerDal.class); customerDal.add();
方案2:直接指定扫描包
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 直接指定要扫描的包路径,等价于配置类中的@ComponentScan context.scan("com.springdemo"); context.refresh(); ICustomerDal customerDal = context.getBean("database", ICustomerDal.class); customerDal.add();
内容的提问来源于stack exchange,提问作者Velihan
相关产品推荐
相关产品推荐

