Spring 与依赖注入相关的注解之 @Autowired/@Qualifier/@Primary

11 篇文章 0 订阅
11 篇文章 0 订阅
关于 IOC(反转控制)和 DI(依赖注入):
背景:

我们在用 spring/springmvc/springboot 框架进行开发时,对下面这种形式的代码应该是最熟悉不过的:
UserController.java:

	package com.uestc.auto.xiaoxie.controller;
	
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Controller;
	
	import com.uestc.auto.xiaoxie.service.BookService;
	
	@Controller
	public class UserController {
	
		@Autowired
		private UserService userService;
		
		// 方法
	}

UserService.java

	package com.uestc.auto.xiaoxie.service;
		
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Service;
	
	import com.uestc.auto.xiaoxie.dao.UserDao;
	
	@Service
	public class UserService {
	
		@Autowired
		private UserDao userDao;
		
		// 方法
	}
	

UserDao.java

	package com.uestc.auto.xiaoxie.dao;
	
	import org.springframework.stereotype.Repository;
	
	@Repository
	public class BookDao {
	
		// 方法等等
		
	}

即我们利用 @Autowird 注解实现组件之间的依赖注入。


用法一:
  1. @Autowired 注解默认优先按照类型去容器中寻找对应的组件。以上述代码为例,在创建 UserService 对象时,需要一个 UserDao 对象;而我们通过配置包扫描(@ComponentScan)以及在 dao 上添加 @Repository 注解,已经将 UserDao 成功注入到了 Spring 容器中,因而通过 @Autowired 就能获取到相应的 bean。
  2. 如果从容器中找到多个类型相同的组件,再以属性名作为 id 去匹配;如果找不到,默认抛异常,可以通过 @Autowired(required=false) 指定非必需
实验一:单独使用 @Autowired
  1. 为了更好地看到测试效果,在 UserDao 中添加一个用于标识的属性:private int flag,即:
	package com.uestc.auto.xiaoxie.dao;
	
	import org.springframework.stereotype.Repository;
	
	@Repository // 如果配置了包扫描,则注入到容器中的 beanName 为 userDao
	public class UserDao {
	
		private int flag = 1;
	
		public int getFlag() {
			return flag;
		}
	
		public void setFlag(int flag) {
			this.flag = flag;
		}
	
		@Override
		public String toString() {
			return "UserDao [flag=" + flag+ "]";
		}
	}

  1. 同时,在配置类中除了通过包扫描的方式外,再通过 @Bean(“userDao2”) 注解注入另一个 UserDao,但是将 UserDao 的 flag 属性设置为 2,并将其 beanName 修改为 userDao2(此时,容器中就会有两个类型为 UserDao 的组件了,其 beanName 分别为 userDao 以及 userDao2)。
@Configuration
@ComponentScan(basePackages={"com.uestc.auto.xiaoxie.controller", "com.uestc.auto.xiaoxie.service", 
		"com.uestc.auto.xiaoxie.dao"})
public class SpringConfig4 {
	@Bean("userDao2")
	public UserDao userDao(){
		UserDao dao = new UserDao();
		dao.setFlag(2);
		return dao;
	}
}
  1. 修改 UserService,添加一个将打印 userDao 属性的方法,方便查看执行效果:
	public void print(){
		System.out.println(userDao);
	}
  1. 单元测试:
	@Test
	public void testAutowired(){
		UserService userService = context.getBean(UserService.class);
		userService.print(); 
	}

测试结果:UserDao [flag=1],因为 UserService 中的属性名为 userDao,所以匹配的是容器中 beanName 为 userDao 的组件,而不是 userDao2 的组件。
此时,容器中确实有两个类型均为 UserDao 的组件。可以通过下面的代码自行测试:

		String[] definitionNames = context.getBeanDefinitionNames();
		for (String name : definitionNames) {
			System.out.println(name + ": " + context.getBean(name));
		}
用法二:配合 @Qualifier 注解使用 @Autowired,用法也很简单。 在这里插入图片描述
实验二:
  1. 在 UserService 的 userDao 属性上添加 @Qualifier(value=“bookDao2”) 注解,表示装配 beanName 为 userDao2 的组件,而不再是根据默认的属性名 userDao 进行装配。
	@Service
	public class UserService {
		@Qualifier(value="userDao2")
		@Autowired
		private UserDao userDao;
		
		public void print(){
			System.out.println(userDao);
		}
	}
  1. 这个时候再进行测试,获取到的就应该是 UserDao [flag=2]。
  2. 此时,容器中依然有两个类型为 UserDao 的组件。
用法三:配合 @Primary 注解一起使用。

在这里插入图片描述

  1. @Primary 注解指定 @Autowired 自动装配时,优先装配哪个组件。例如,可以先将上面的 UserService 中的 @Qualifier 注解注释掉,并在 @Bean 修饰的方法上添加 @Primary 注解。
  2. @Primary 还可以与 @Qualifier 一起使用。再放开 @Qualifier 注释,重新测试,发现装配的依然是 @Qualifier 注解指定的 bean(可以理解为:@Qualifier 是根据 beanName 来装配 bean,beanName 对应不上的话,管你什么优先级)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值