【问题标题】:org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userDAO' is defined - context not being passedorg.springframework.beans.factory.NoSuchBeanDefinitionException:没有定义名为“userDAO”的bean - 未传递上下文
【发布时间】:2017-03-13 04:44:48
【问题描述】:

这是我的文件和目录:

Spring-Module.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 

<import resource="Spring-Datasource.xml" />
<import resource="Spring-User.xml" />

Spring-Datasource.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="VALID_URL" />
    <property name="username" value="USER" />
    <property name="password" value="PASS" />
</bean>

Spring-User.xml

<beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="userDAO" class="hello.JdbcUserDAO">
    <property name="dataSource" ref="dataSource" />
</bean>

Application.java

package hello;
<import statements>
@SpringBootApplication
public class Application {

public static void main(String[] args) {
    ApplicationContext context =
            new ClassPathXmlApplicationContext("Spring-Module.xml");
    SpringApplication.run(Application.class, args);

    UserDAO userDAO = (UserDAO) context.getBean("userDAO");
    }
}

RegistrationController.java

package hello;
@RestController
public class RegistrationController implements ApplicationContextAware {

private static final String template = "Hello, %s!";
//    @Autowired <-- using this instead of interface doesn't work either
private static ApplicationContext context;
private final AtomicLong counter = new AtomicLong();

@RequestMapping(value = "/api/register", method = RequestMethod.POST)
public Response registerUser(@RequestParam Map<String,String> req) {


    User user = new User(counter.incrementAndGet(),
                        req.get("first"), req.get("last"), req.get("email"), 
                        req.get("age"), Double.parseDouble(req.get("height")), 
                        Double.parseDouble(req.get("weight")), Double.parseDouble(req.get("bmi"))
                        );

    UserDAO userDAO = (UserDAO) context.getBean("userDAO"); // <--- error here
    userDAO.insert(user);


    return new Response(counter.get(), "200");
}

public static ApplicationContext getApplicationContext() {
    return context;
}

@Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
    this.context = ac;
    }

}

当我从 Application 类访问 bean userDAO 时,一切都按预期正常运行。问题是当我尝试使用上下文从我的路由类访问 userDAO 时,它会抛出错误“找不到 bean userDAO”。因此,我怀疑必须在我的路线内再次创建上下文?

我对 Spring 比较陌生,完全被难住了!我会尽力澄清你们的任何问题。

编辑:添加目录

   src/main/java/hello
      /resources
                /Spring-User.xml
                /Spring-Module.xml
                /Spring-Datasource.xml

【问题讨论】:

  • 这是因为您在控制器类中提供了错误的 bean 名称。您应该提供 context.getBean("userDAO");而不是 context.getBean("UserDAO");
  • 抱歉,我提出问题时打错字了。我已经更新了我实际调用的代码。我一直在调用“userDAO”
  • 尝试使用以下代码自动装配applicationContext @Autowired private ApplicationContext context;
  • 我之前有过这段代码,但我又试了一次,还是同样的错误。你知道什么可能导致错误吗?
  • 你正在加载你的上下文,然后启动 spring boot 应用程序。您现在有 2 个不相关的应用程序上下文。无需加载上下文,只需将 `@ImportResource("classpath:Spring-Module.xml")' 添加到您的 spring-boot 应用程序并删除应用程序上下文的实例化。

标签: java spring spring-mvc javabeans


【解决方案1】:

我找到了解决方案 - 感谢您的帮助。我不确定为什么会这样(或者更确切地说,为什么实现接口不起作用)。

RegistrationController.java

package hello;


@RestController
public class RegistrationController implements ApplicationContextAware {

@Autowired
private static ApplicationContext context;

@RequestMapping(value = "/api/register", method = RequestMethod.POST)
public Response registerUser(@RequestParam Map<String,String> req) {
    context = new ClassPathXmlApplicationContext("Spring-Module.xml"); // <--- added this line


    User user = new User(counter.incrementAndGet(),
                    req.get("first"), req.get("last"), req.get("email"), 
                    req.get("age"), Double.parseDouble(req.get("height")), 
                    Double.parseDouble(req.get("weight")), Double.parseDouble(req.get("bmi"))
                    );

    UserDAO userDAO = (UserDAO) context.getBean("userDAO"); 
    userDAO.insert(user);


    return new Response(counter.get(), "200");
}

public static ApplicationContext getApplicationContext() {
    return context;
}

@Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
    this.context = ac;
    }

}

【讨论】:

  • 这是基于我的回答和想法,您可以关注并且应该这样做。但不要投票,发布答案对我来说非常失望。我现在将删除我的答案。祝你好运
  • 因为我已经要求你这样实现 -- new ClassPathXmlApplicationContext("Spring-Module.xml");
  • 是的,这来自您的回答。不同之处在于您建议将其设为成员变量,而不是在函数内部创建变量 - 这似乎有所不同。感谢您的帮助!
  • 这取决于你,你可以在任何地方创建,我建议你在全局变量中使用。
  • 这不是解决方案...它最终会崩溃。
【解决方案2】:

您实际上需要为带注释的组件设置类路径扫描并打开注释配置

<context:annotation-config/>
<context:component-scan base-package="com.example.dao, com.example.service, com.example.controller, etc..."/>

但 2016 年最好的建议是完全忘记 xml 配置并开始使用 java 配置。

【讨论】:

  • 你知道为什么会这样吗?我对 Spring 还是很陌生,正在尝试了解它是如何工作的。另外,这段代码应该去哪里?谢谢
  • 您的 2016 年方法很好,但问题所有者需要了解 @Autowired 并需要删除 xml beans 声明。第一次,我先喜欢XML,等他成熟了再改成你的回答这样的注解。
  • 补充:刚接触 Spring 框架的人可能会对遵循哪种方法感到困惑。例如 XML 或注释或 Java 配置。到目前为止,Spring 团队建议遵循基于 JavaConfig 的方法,因为它提供了更大的灵活性。但是没有一种万能的解决方案。必须根据自己的应用需求选择方法。
  • @Steven 它必须进入你的 Spring-Module 文件。您告诉 spring DI 容器它必须搜索指定包中的组件,它们是带注释的类。相反,您可以在 xml 中手动定义每个 bean,这在大型代码库中似乎并不实用。
猜你喜欢
  • 2012-03-25
  • 2012-11-20
  • 2014-11-14
  • 2013-02-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-24
  • 2013-01-25
相关资源
最近更新 更多