我一直在修改我的类,以避免在我的控制器中new
(让Spring的容器管理它)上的 StudentService
运算符。我需要Student student;
字段注入StudentService
,但不是注入student
,而是注入异常:
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();
}
StudentService:
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
没有例外,但它会产生
NAME:null
如果我删除了@Service
并将StudentService
加载为<bean class="com.StudentService".. >
并通过应用程序上下文手动加载它,那么它就能正常工作。
我的意思是@Service
无法自动装配
答案 0 :(得分:2)
Spring知道两种以上的方式来声明&#34; bean&#34; (它可以用来注入的对象)。一个是xml:
<bean id="ss" class="com.StudentService" />
这将导致spring通过执行"ss"
创建名为new com.StudentService(...)
的bean。它甚至应该通过查找匹配的其他bean来尝试找出构造函数参数。生成的对象存储在应用程序上下文中以供将来使用。例如。当某些地方请求获取StudentService
类型的bean或名为"ss"
的bean时。
@Service
和@Component
以及其他一些人一样,会让spring对待这个附加到bean的类。该名称将来自班级名称:它只是低级的。它还将new
该类型的实例并注意所有依赖项。 XML和@ -annotation配置的bean都可以在应用程序上下文中使用。
在你的情况下,你用两种不同的方式告诉spring:你希望com.StudentService
可以作为bean使用,一旦通过xml明确命名"ss"
,一旦隐式命名为{{1在java。
现在,当您在控制器中请求与"studentService"
类型相匹配的bean时,
Student
它有2个同样优秀的候选人,无法决定注入哪一个。这是你目前的例外。
要解决此问题,您可以只声明1个bean(最好),或者通过提供名称来限定您的意思。例如
@Autowired
Student student;
这几乎就是你以后用
做的事情@Autowired
@Qualifier("ss")
Student student;
当你将两者结合起来时
StudentService ss = (StudentService) appContext.getBean("ss");
现在你有2个独立的bean / @Autowired
@Qualifier("st")
Student student;
...
StudentService ss = (StudentService) appContext.getBean("ss");
ss.setName("bravo");
System.out.println("NAME : " + student.getN());
实例,它们都是&#34;单身&#34; (他们的豆子名字)。您将名称设置为1,并读取另一个的名称。预期的结果是StudentService
bean的名称仍为空。
答案 1 :(得分:1)
让我们看一下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 "";
}
在此方法中,您需要创建名为StudentService
的{{1}}对象。在下面,您调用ss
接口方法,将setName
名称设置为bravo。 但是,当您致电StudentService
时,您正在检索其他对象的名称。
要解决此问题,您可以检索由student.getN()
管理的Student
对象:
StudentService
但是为了特殊性,我建议将两者分离,只使用@Service
public class StudentService {
@Autowired
Student student;
public Student getStudent() {
return student;
}
public void setName() {
this.student.setName(Alfred);
}
}
Student
而不使用服务。