Spring 中接口的 bean 是如何注入的?

这个问题困扰了我好久,一直疑问这个接口的bean是怎么注入进去的?因为只看到使用@Service注入了实现类serviceImpl,使用时怎么能获取的接口,而且还能调用到实现类的方法,难道这个接口是在什么时候自动注入了进去,且和实现类关联上了? **接口**: ```java public interface TestService { public String test(); } ``` 实现类impl ```java @Service public class TestServiceImpl implements TestService { @Override public String test() { return "TestServiceImpl"; } } ``` **Controller的调用:** ```java @RestController public class TestCtl { @Autowired private TestService testService; @RequestMapping("/test") public String test() { return testService.test(); } } ``` 请求结果: ![image.png](https://images.codewd.com/e017b6d9cb80627a4429c8b5c9826f49.png)

1 个回答

  • java小生
    见过花就好,何必在意花属于谁。
    并没有注入接口的bean,只注入了实现类serviceImpl的bean,接口只是用来接收的。 这里就要说到@Autowired/@Resource的注入原理了:@Autowired是Spring的注解,Autowired默认先按byType,如果发现找到多个bean,则,又按照byName方式比对,如果还有多个,则报出异常;@Resource 是JDK1.6支持的注解,默认按照名称(Byname)进行装配, 如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。 再来说Controller获取实例的过程:使用@Autowired,程序在spring的容器中查找类型是TestService的bean,刚好找到有且只有一个此类型的bean,即testServiceImpl,所以就把testServiceImpl自动装配到了controller的实例testService中,testService其实就是TestServiceImpl实现类; 如果使用的是@Resource,则是先在容器中查找名字为testService的bean,但并没有找到,因为容器中的bean名字是TestServiceImpl(如果@Service没指定bean的value属性,则注入bean的名字就是类名,如果指定了则是指定的名字),然后再通过类型查找TestService类型的bean,找到唯一的了个TestService类型bean(即TestServiceImpl),所以就自动装配实例成功了。
    发布于 2021-06-17 11:27 •IP属地 安徽
    举报
    评论
    收藏