默認根據類型,匹配不到則根據bean名字
1.聲明一個service接口
public interface HelloService { void sayHello(); }
2.service接口的實現類,此時bean名字是 helloServiceImpl
@Service public class HelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("say hello impl"); } }
3.增加一個Controller,注入service
// 生成一個bean,名字為 helloController @Controller public class HelloController { @Autowired private HelloService helloService; public void hello() { helloService.sayHello(); } }
4.測試①:
public class AppTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloController controller = (HelloController) context.getBean("helloController"); controller.hello(); } }
結果如下

成功將Service層的實現類注入到Controller層中,可以把步驟3 代碼修改一下
// 生成一個bean,名字為 helloController @Controller public class HelloController { @Autowired private HelloService abc; public void hello() { abc.sayHello(); } }
結果也是可以的,因為@Autowired 第一是按照類型去匹配的,此時IoC容器中HelloService 接口只有一個實現類,所以屬性名字怎么寫都沒關系,都可以注入進去
測試②:增加一個實現類,此時bean名字是 newServiceImpl
@Service public class NewHelloServiceImpl implements HelloService { @Override public void sayHello() { System.out.println("new say hello impl"); } }
現在IoC容器中有兩個 HelloService接口的實現類,繼續運行測試方法,結果為
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'helloController':
Unsatisfied dependency expressed through field 'abc';
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.convict.service.HelloService' available:
expected single matching bean but found 2: helloServiceImpl,newHelloServiceImpl
因為一個接口有多個實現,所以@Autowired 就按照屬性名字去找,即找一個名字為 abc的bean注入,然而IoC容器不存在一個名字叫abc的 bean,因此報錯,把屬性名改為下面任意一種就可以匹配到了
// 生成一個bean,名字為 helloController @Controller public class HelloController { @Autowired private HelloService helloServiceImpl; @Autowired private HelloService newHelloServiceImpl; public void hello() { helloServiceImpl.sayHello(); newHelloServiceImpl.sayHello(); } }

測試③:
那我就要把屬性名叫 abc,同時有多個實現,而且還能注入,那么在聲明組件的時候取個名字就好了,比如
@Service("abc")
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("say hello impl");
}
}
然后Controller 注入的還是abc,結果注入成功
// 生成一個bean,名字為 helloController @Controller public class HelloController { @Autowired private HelloService abc; public void hello() { abc.sayHello(); } }

測試④:
屬性名叫 abc,同時有多個實現,同時可以注入,且不在注解處聲明bean 的名字,那么這時候使用新的注解@Qualifier 配合@Autowired 一起使用
// 生成一個bean,名字為 helloController @Controller public class HelloController { @Autowired @Qualifier("helloServiceImpl") private HelloService abc; public void hello() { abc.sayHello(); } }

@Qualifier是指定 一個bean的名字
總結:
1.一個接口只有一個實現的情況下,屬性名字怎么寫都無所謂,因為按照類型匹配就只有一個bean
2.一個接口多個實現的情況下:
① 屬性名字跟組件名字一致,組件名字可以在聲明的時候指定,比如 @Service("abc")
② 屬性名字跟組件名字不一致,配合@Qualifier 注解指定組件名字
