当前位置: 首页 > 知识库问答 >
问题:

即使依赖关系由Spring容器管理,也无法自动连接服务

党建义
2023-03-14

我一直在修改我的类以避免new运算符在我的控制器中的学业服务(让Spring的容器管理它)上。我需要学生;那里的字段被注入了学业服务,但它没有被注入学生,而是被注入了一个异常,上面写着:没有限定类型[com的bean。学生]被定义:预期单个匹配bean,但找到了2:学生服务,ss

我想打印这个程序

姓名:bravo

学生:

package com;
public interface Student {
    public String getN();
}

学生服务:

package com;
import org.springframework.stereotype.Service;
@Service
public class StudentService implements Student{
String name;
    @Override
    public String getN() {
      return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

控制器

 package com;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class TheController {

    @Autowired
    private ApplicationContext appContext;

    @Autowired
    Student student; 

    @RequestMapping("/")
    public String aMethod() {

        StudentService ss = (StudentService) appContext.getBean("ss");
        ss.setName("bravo");

        System.out.println("NAME : " + student.getN());
        // while "NAME : " + ss.getN() will work, of course
        return "";
    }
}

调度程序servlet

...
 <context:component-scan base-package="com" /> 

 ...
  <bean id="ss" class="com.StudentService" />

...

编辑:如果我这样做:

@Service ("st")

public class StudentService implements Student{

和这个(在控制器中)

@Autowired
@Qualifier("st")
Student student; // tipenya interface

没有例外,但它产生

名称:null

如果我取消了服务并将学生服务加载为

我是说那项服务怎么不能自动连线

共有2个答案

米修平
2023-03-14

让我们看看aMethod

@RequestMapping("/")
public String aMethod() {

    StudentService ss = (StudentService) appContext.getBean("ss");
    ss.setName("bravo");

    System.out.println("NAME : " + student.getN());
    // while "NAME : " + ss.getN() will work, of course
    return "";
}

在此方法中,您将创建一个名为ss学生服务对象。就在下面,您调用setName接口方法,该方法将学生服务名称设置为bravo。但是,当您调用student.getN()时,您正在检索不同对象的名称。

要解决此问题,您可以检索由StudentService管理的Student对象:

@Service
public class StudentService {

    @Autowired
    Student student;

    public Student getStudent() {
        return student;
    }

    public void setName() {
        this.student.setName(Alfred);
    }
}

但是出于特性的考虑,我建议将两者解耦,只使用您的学生setName()而不使用服务。

黄宏毅
2023-03-14

Spring知道两种以上的方法来声明“bean”(它可以用来注入的对象)。一种是xml:

<bean id="ss" class="com.StudentService" />

这将导致spring通过执行new com创建一个名为“ss”的bean。学生服务(…) 。它甚至应该通过查找其他匹配的bean来找出构造函数参数。生成的对象存储在应用程序上下文中,以供将来使用。E、 g.当某个地方请求获取类型为StudentService或名为“ss”的bean时。

@Service

以及@Component和其他一些将导致Spring将附加到的类视为bean。该名称将派生自类名:它只是小写的。它还将new该类型的实例并照顾所有依赖项。XML和@-注释配置的bean都将在应用程序上下文中可用。

在您的例子中,您可以用两种不同的方式告诉spring做同样的事情:您希望拥有com。StudentService可用作bean,一次通过xml显式命名为“ss”,一次在java中隐式命名为“StudentService”。

现在,当您在控制器中请求一个与学生类型匹配的bean时,如下所示

@Autowired
Student student; 

它有两个同样好的候选者,但无法决定注入哪一个。这是您当前的例外。

为了解决这个问题,您可以只声明1个bean(最好),或者通过提供名称来限定您所指的bean。例如

@Autowired
@Qualifier("ss")
Student student;

这几乎就是你以后要做的

StudentService ss = (StudentService) appContext.getBean("ss");

当你把两者结合起来

@Autowired
@Qualifier("st")
Student student;

...

StudentService ss = (StudentService) appContext.getBean("ss");
ss.setName("bravo");

System.out.println("NAME : " + student.getN());

现在您有了两个独立的bean/StudentService实例,它们都是“singleton”(与其bean名称相同)。设置其中一个的名称,然后读取另一个的名称。预期的结果是,“st”bean的名称仍然为空。

 类似资料:
  • 我正在使用Gradle的Spring Boot框架。我知道,为了包含一些Spring依赖项,我可以引用“starters”而不显式定义版本;该版本将由我选择的Spring Boot版本控制,它是Spring Boot Gradle插件的版本。示例(省略非相关的分级代码): 请注意,没有为我的应用程序依赖项定义显式版本。 我如何确保我为那些依赖项使用的版本与我的其他Spring Boot依赖项兼容?

  • Maven的核心功能之一是依赖管理。 一旦我们处理多模块项目(由数百个模块/子项目组成),管理依赖项是一项艰巨的任务。 Maven提供高度的控制来管理这些场景。 传递依赖发现 通常情况下,当一个库(比如A)依赖于其他库时,比如说B.如果另一个项目C想要使用A,那么该项目也需要使用库B. Maven有助于避免此类要求发现所需的所有库。 Maven通过读取依赖项的项目文件(pom.xml),找出它们的

  • 我创建了一个将使用spring boot和Gradle的java项目。我想为不同的环境配置配置文件(在我的本地机器上进行开发,在服务器场机器上进行集成测试的systemtest等)。我将在内存数据库中使用h2用于开发环境,将SqlServer用于systemtest环境。在build.gradle中,我定义了以下依赖项 我创建了一个application.yml文件application-deve

  • Ember使用NPM和Bower来管理在针对NPM的package.json和针对Bower的bower.json中定义的依赖关系。 例如,您可能需要在开发Ember应用程序时为Ember安装的样式表安装SASS。 要实现此目的,请使用Ember Addons共享可重用库。 如果要安装任何CSS框架或JavaScript datepicker依赖项,请使用Bower包管理器。 Addons Emb

  • 问题内容: 我有一个二进制文件,其中ldd显示了意外的依赖项和libicuuc(来自“ icu”)。 由于在该系统上libxml动态依赖于libicuuc,因此ldd最终会找到它是有意义的,但是是否期望libicuuc也出现在A的ldd输出中?是否有一些命令仅检索链接为依赖项依赖关系的库? 问题答案: 显示启动应用程序或加载共享库时需要加载的所有库。 仅显示二进制文件的直接依赖项。 是否有一些命令

  • 这是我的当前设置:ProjectRepo: ProjectService: ProjectRestController: