gpt4 book ai didi

java - 即使依赖项由 Spring 容器管理后也无法 Autowiring 服务

转载 作者:行者123 更新时间:2023-12-01 21:28:26 25 4
gpt4 key购买 nike

我一直在修改我的类以避免 new StudentService 上的运算符(让 Spring 的容器管理它)在我的 Controller 中。我需要Student student;那里的字段被注入(inject) StudentService但不是得到 student注入(inject)它会注入(inject)一个异常说: No qualifying bean of type [com.Student] is defined: expected single matching bean but found 2: studentService,ss

我想要这个程序打印

NAME : 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;
}

}

Controller

 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{

还有这个(在 Controller 中)

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

没有异常(exception),但它会产生

NAME :null

如果我去掉@Service并加载StudentService<bean class="com.StudentService".. >并通过应用程序上下文手动加载它,然后它就会工作。

我的意思是那怎么样@Service无法 Autowiring

最佳答案

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

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

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

@Service

以及@Component和其他一些将导致spring将其附加的类视为bean。该名称将从类名派生:它只是小写。它还会新建该类型的实例并处理所有依赖项。 XML 和@-annotation 配置的bean 都将在应用程序上下文中可用。

在你的例子中,你用两种不同的方式告诉 spring 做同样的事情:你希望 com.StudentService 可以作为 bean 使用,一旦显式命名“ss” 通过 xml,曾经在 java 中隐式命名为 "studentService"

现在,当您在 Controller 中请求一个与 Student 类型匹配的 bean 时,如下所示

@Autowired
Student student;

它有 2 个同样优秀的候选者,但无法决定注入(inject)哪一个。这是您当前的异常。

要解决该问题,您可以只声明 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());

现在发生的情况是,您现在有 2 个独立的 bean/StudentService 实例,它们都是“单例”(用它们的 bean 名称表示)。您设置其中一个的名称,然后读取另一个的名称。预期结果是 "st" bean 的名称仍然为 null。

关于java - 即使依赖项由 Spring 容器管理后也无法 Autowiring 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37736283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com