【spring注解驱动开发】- 自动装配 - @Autowired&@Qualifier&@Primary

本博客demo源码地址
https://github.com/suchahaerkang/spring-annotation.git

这篇文章我们开始学习spring的自动装配,即DI(依赖注入):将IOC容器中互相依赖的组件自动赋值
对于自动装配spring提供了一些相关的注解,我们首先研究一下@Autowired这个注解

1 @Autowired

@Autowired注解的作用是去容器中找它标注的那个组件,如果找到了就将其赋值
首先我们创建三个组件分别为BookController,BookService, BookDao,并且BookController依赖BookService, BookService依赖BookDao,然后我们通过@Autowired的方式将依赖注入到相应的组件中去

/**
 * @description:
 * @author: sukang
 * @date: 2020-03-04 15:09
 */
@Controller
public class BookController {

    @Autowired
    private BookService bookService;
}

/**
 * @description:
 * @author: sukang
 * @date: 2020-03-04 15:09
 */
@ToString
@Service
public class BookService {

    @Autowired
    private BookDao bookDao;
}

/**
 * @description:
 * @author: sukang
 * @date: 2020-03-04 15:09
 */
@Repository
public class BookDao {
}

然后我们用@ComponentScan将这个三个组件注册到容器中去

/**
 * @description:
 * @author: sukang
 * @date: 2020-03-07 14:05
 */
@ComponentScan({"com.wolfx.controller","com.wolfx.service", "com.wolfx.dao"})
@Configuration
public class MainConfigOfAutowired {

}

写个测试用例

//测试@Autowired
@Test
public void test01(){
    //创建容器
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
    //从容器中获取BookService组件
    BookService bookService = applicationContext.getBean(BookService.class);
    System.out.println(bookService);
}

运行结果
在这里插入图片描述
@Autowired自动注入组件的时候,首先是去容器找那个组件对应的类型,如果容器中只有一个对应组件的类型,那么就注入这个组件
那么问题来了,如果容器中存在多个类型相同的组件,@Autowired将如何自动装配呢。下面我们向容器中再注册一个BookDao的组件,id为bookDao2,并且将它的lable属性赋值为2

@Bean("bookDao2")
public BookDao bookDao(){
    BookDao bookDao = new BookDao();
    bookDao.setLable(2);
    return bookDao;
}

运行结果
在这里插入图片描述
从结果我们知道,@Autowired注入的是属性lable=1,类型为BookDao的组件,之所以自动注入lable=1的组件而不是lable=2的组件,是因为@Autowired标注的组件BookDao在BookService组件中的属性名为bookDao。所以我们得出结论,如果容器中有多个相同类型的组件,那么@Autowired将自动注入容器中id为属性名的那个实例
ps:如果@Autowired标注属性,自动动注入的时候在容器中没有找到属性相关类型的组件,将会报在容器中找不到那个组件的错误,我们把BookDao组件注册到容器中的两种方法都注释掉,运行结果如下:
在这里插入图片描述
解决方案将@Autowired的改为false,默认为true

@Autowired(required = false)
private BookDao bookDao;

运行结果
在这里插入图片描述

2 @Qualifier

@Qualifier的作用是:如果容器中有多个类型相同的实例,配合注解@Autowired自动注入想要的那个实例
下面我们来学习这个注解
比如我们想要在BookService中自动注入id为bookDao2的实例

@Qualifier("bookDao2")
@Autowired
private BookDao bookDao;

运行结果
在这里插入图片描述

3 @Primary

@Primary的作用:容器中注册了多个相同类型的组件情况下,如果在自动转配的时候想要某个实例优先被装配,那么你可以在注册组件的时候标注上@Primary这个注解
下面我们学习一下。比如说我们希望id为bookDao2的实例优先自动装配,那么我们在给bookDao2注册到容器的时候,标注上@Primary

@Primary
@Bean("bookDao2")
public BookDao bookDao(){
    BookDao bookDao = new BookDao();
    bookDao.setLable(2);
    return bookDao;
}

为了怕影响测试结果,把上面我们测试的@Qualifier注解注释掉
运行结果如下
在这里插入图片描述

发布了78 篇原创文章 · 获赞 32 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/suchahaerkang/article/details/104713898