为什么不创建bean?

时间:2019-09-02 12:46:37

标签: java spring applicationcontext

我的问题:
为什么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

有什么主意如何使其更好地工作?

2 个答案:

答案 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);