一个@Autowired案例

给出src的包:Dao接口和Dao的实现类
image.png
BookDao.java:只有一个save方法

  1. package com.itheima.boot.dao;
  2. public interface BookDao {
  3. public void save();
  4. }

BookDaoImpl.java:实现BookDao接口中的save方法

  1. package com.itheima.boot.dao.impl;
  2. import com.itheima.boot.dao.BookDao;
  3. import org.springframework.stereotype.Repository;
  4. // 是一个可以被spring管理的bean
  5. @Repository
  6. public class BookDaoImpl implements BookDao {
  7. @Override
  8. public void save() {
  9. System.out.println("Book Dao is running ...");
  10. }
  11. }

写一个Junit测试

  1. package com.itheima.boot;
  2. import com.itheima.boot.dao.BookDao;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. @SpringBootTest
  7. class Springboot04JunitApplicationTests {
  8. // 1.注入需要测试的对象,使用@Autowired实现自动装配
  9. @Autowired
  10. private BookDao bookDao;
  11. @Test
  12. void contextLoads() {
  13. // 2.执行要测试的对象对应方法
  14. bookDao.save();
  15. }
  16. }

输出结果
image.png

再说@Autowired原理

  1. @Autowired原理:
  2. 举例:@Autowired
  3. private BookDao bookDao;
  4. 1)、先按照类型去容器中找到对应的组件;bookDao = ioc.getBean(BookDao.class)
  5. ①、找到一个:找到就赋值
  6. ②、没找到就报异常
  7. ③、按照类型可以找到多个?找到多个如何装配上?
  8. a、类型一样就按照变量名为ID继续匹配
  9. Ⅰ、匹配上就装配
  10. Ⅱ、没有匹配?报错
  11. 原因:因为我们按照变量名作为id继续匹配的
  12. 使用@Qualifier指定一个新的id
  13. 找到就匹配

对于a、这种情况,按照变量名作为id继续匹配,还是匹配不到的话,可以使用新的注解:
@Qualifier:指定一个新id作为id,让spring不使用变量名作为id

使用@Autowired注解注入,是写接口名字还是实现类的名字?

@Repository注解的是接口BookDao的实现类BookDaoImpl,@Autowired用来自动装配private BookDao bookDao,为什么最后得到的是BookDaoImpl的实例?

这其实是创建了实现类的对象但引用了接口类型,即”BookDao bookDao = new BookDaoImpl()”,这个是Java多态性(向上转型)的一种应用。在实现类加@Repository注解,意思就是new BookDaoImpl(),而在测试时定义属性BookDao bookDao就是将new出来BookDaoImpl对象向上转型为BookDao类型。

总结

用例子总结:
@Autowired
private BookService bookService;
总结:autowired 为组件自动赋值,自动查找ioc容器,找到就赋值,查找的方式是从类型寻找,有可能找到多个,比如说有一个继承于要查找的类,如果是多个就按照变量名作为id继续匹配
举例说:查找到多个相同的类是BookService 和 BookServiceExtend,这 个 时候会根据你要查找的bookservice 来查找id,BookService 的id默认是bookservice,BookServiceExtend的id默认是bookServiceExtend,一查找就只匹配上BookService 类了

如果现在把例子该了:改成bookService2了
@Autowired
private BookService bookService2;
Spring容器先查找BookService类,一找就找到两个类(BookService 和BookServiceExtend),然后查找id,发现都不匹配,会直接报错
这个时候诞生了@Qualifier注解,让spring不使用bookService2作为id去查找,而是使用一个比如说bookService去查找,作为新的id去查找
@Qualifier(”bookService”)
@Autowired
private BookService bookService2;
@Qualifier注解找不到就报错,找到就装配

所以发现Autowired标注的自动装配的属性默认是一定装配上的,找到就装配,找不到就拉倒
可以在Autowired(request = false)默认是true,找不到就会报错,置为false后,找不到会置为null
@Qualifier(”bookService”)
@Autowired(request=false)
private BookService bookService2;

方法上有@Autowired的话,对于参数的类型是引入进来的,import进来的:
1)、这个方法也会在bean创建的时候自动运行
2)、这个方法上的每一个参数都会自动注入值