我的问题:
为什么Spring自动扫描对我不起作用?
我不想使用bean.xml
文件,而是让系统自行扫描Bean。
我使用Spring AnnotationConfigApplicationContext
。
Bean具有@Component
批注,其包包含在scan
中,但是当尝试获取Bean时有NoSuchBeanDefinitionException
。
我在以下结构中有一个maven项目
- module A
- module B (depends on A)
- module C (depends on B)
(通过@Configuration
类进行初始化也是一个问题,因为用于初始化应用程序上下文的代码在module A
中是通用的,而Bean在module B
中并且不能从A实例化。)< / p>
在module A
中有一个代码可以加载ApplicationContext
。
我有一个用于获取应用程序上下文的singelton。
package com.mycode.my;
public class AppContext {
private static ApplicationContext ctx;
public static ApplicationContext getApplicationContext() {
if (ctx == null)
ctx = new AnnotationConfigApplicationContext("com.mycode");
return ctx;
}
}
模块B中有接口和Bean在使用它
package com.mycode.third;
public interface MyBean{
void runSomething();
}
package com.mycode.third;
@Component
public class MyBeanImpl implements MyBean{
public void runSomething(){
}
}
问题: 当我从模块C尝试获取bean时:
public class MyImpl{
public void doTheJob(){
MyBean bean1 = AppContext.getApplicationContext().getBean("myBean")
}
}
我得到:
org.springframework.beans.factory.NoSuchBeanDefinitionException
有什么主意如何使其更好地工作?
答案 0 :(得分:3)
默认情况下,组件的bean名称(或任何其他bean构造型)是:类名,首字母小写。因此您的bean被命名为myBeanImpl
。
在这里,您可以在查找中将接口名称指定为Bean名称。
它不能以这种方式工作,因为如果Spring将接口用作bean的名称,那么您将无法实现该接口的多个实现。
有什么主意如何使其更好地工作?
更好的方法是不直接使用spring工厂获取bean,而是使用自动装配功能对其进行注入。
@ContextConfiguration(classes = MyAppConfig.class)
public class MyImpl{
private MyBean bean;
// Autowire constructor
public MyImpl(MyBean bean){
this.bean = bean;
}
public void doTheJob(){
// you can use bean now
}
}
一个更好的选择是使用Spring Boot,只要您遵守标准,它就需要您进行一些其他配置。
答案 1 :(得分:1)
如果要按myBean
的名称查找,请将value添加到组件:
@Component("myBean")
public class MyBeanImpl implements MyBean {
该值可能表示建议使用逻辑组件名称,以在自动检测到组件时将其转换为Spring bean。
或者通过类而不是字符串值获取
getAppContext().getBean(MyBean.class);