(8)spring注解学习之@Autowired

Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;

1. @Autowired 自动注入

1.1 注入规则

1)、默认优先 按照类型 去容器中找对应的组件:
	    applicationContext.getBean(BookDao.class);
		找到就赋值
2)、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
		applicationContext.getBean("bookDao")
3)、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,	
						   而不是使用属性名
4)、自动装配默认一定要将属性赋值好,没有就会报错;可以使用
		@Autowired(required=false);
5)、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;
			  也可以继续使用@Qualifier指定需要装配的bean的名字
1.1.1 默认优先 按照类型 去容器中找对应的组(此时容器里面只有一个 【 BookDao】实例)

BookService 和 BookDao 因为 【@ComponentScan + @Service】被加入容器中 但是因为 BookService 里面包含 【BookDao 】,所以 BookService 里面加了 @Autowired直接拿到的就是 容器里面的 BookDao ,如果不加的话,BookService 里面的 BookDao = null

@Service
public class BookService {
	
	//@Qualifier("bookDao")
	//@Autowired(required=false)
	//@Resource(name="bookDao2")
	//@Inject
	@Autowired
	private BookDao bookDao;
}
  • IOCTest_Autowired文件
  • 发现 BookService 里面的【 BookDao】和容器里面的 【 BookDao】是同一个
    在这里插入图片描述
1.1.2 多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
  • @Repository注解的bean注入到容器中的名称是”bookDao “
    在这里插入图片描述
  • 另外又通过config文件 在容器中注入了另外一个 BookDao,名称是bookDao2
    在这里插入图片描述
  • 容器内有两个 bookDao,所以通过 applicationContext.getBean(BookDao.class)获取不到了,需要通过 名称来获取;
BookDao bean = (BookDao) applicationContext.getBean("bookDao2");
  • 结果如下:
    BookService里面还是 bookDao ,因为@Autowired 里面默认 自动导入 对应 BookDao的bookDao,
    在这里插入图片描述
1.1.3 使用@Qualifier指定需要装配的组件的id,而不是使用组件的属性名

在这里插入图片描述

  • 更改了之后,BookService里面变成了 bookDao2
    在这里插入图片描述
1.1.4 自动装配默认一定要将属性赋值好,没有就会报错
  • 当容器中没有 BookDao 的任何组件时,即没有扫描 BookDao这个类,或者没有手动注入BookDao 这个组件时,如果此时 【BookService】还要导入 @Autowired BookDao,会报错(因为BookService 初始化需要BookDao,但是容器中没有这个bean实例,所以会报错):
    在这里插入图片描述
  • 所以,@Autowired就需要设置(设置了之后表明这个属性不是必须的,默认可以为null)
@Autowired( required=false)
1.1.5 Spring进行自动装配的时候,默认使用首选的bean–@Primary
  • 将 MainConifgOfAutowired 文件中 的 bookDao2 设置为首选
    在这里插入图片描述
  • BookService 里面
    在这里插入图片描述
  • 结果如下:BookService 里面导入的是bookDao2
    在这里插入图片描述

2 @Resource(JSR250)和@Inject(JSR330)[java规范的注解]

  • @Resource 按照 组件名称(byName) 进行装配,找不到与名称匹配的bean时才按照 类型(byType)进行装配
  • @Autowired 是 按照 类型(byType)装配
@Resource:
	可以和@Autowired一样实现自动装配功能;默认是按照 组件名称 进行装配的;
	不能支持@Primary功能,不支持@Autowired(reqiured=false);
	
@Inject:
	需要导入javax.inject的包,和Autowired的功能一样。
	没有required=false的功能;

3 @Autowired:构造器,参数,方法,属性;都是从容器中获取参数组件的值

  • [标注在方法位置]:
    @Bean+方法参数;参数从容器中获取
    默认不写@Autowired效果是一样的;都能自动装配
//默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
@Component
public class Boss {		
	private Car car;
	
	//构造器要用的组件,都是从容器中获取
	public Boss(Car car){
		this.car = car;
		System.out.println("Boss...有参构造器");
	}
	
	public Car getCar() {
		return car;
	}
	
	@Autowired 
	//标注在方法,Spring容器创建当前对象,就会调用方法,完成赋值;
	//方法使用的参数,自定义类型的值从ioc容器中获取
	public void setCar(Car car) {
		this.car = car;
	}
}
  • [标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的==@Autowired可以省略==参数位置的组件还是可以自动从容器中获取
//构造器要用的组件,都是从容器中获取
	@Autowired
	public Boss(Car car){
		this.car = car;
		System.out.println("Boss...有参构造器");
	}
  • [放在参数位置]:
public void setCar(@Autowired  Car car) {
		this.car = car;
}

4. AutowiredAnnotationBeanPostProcessor解析完成自动装配功能

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx);
	自定义组件实现xxxAware;在创建对象的时候,会调用接口规定的方法注入相关组件;Aware;
	把Spring底层一些组件注入到自定义的Bean中;
	xxxAware:功能使用xxxProcessor;
		ApplicationContextAware==》ApplicationContextAwareProcessor;

实现了相关的ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware接口

@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {
	
	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		
		System.out.println("传入的ioc:"+applicationContext);
		this.applicationContext = applicationContext;
	}

	@Override
	public void setBeanName(String name) {		
		System.out.println("当前bean的名字:"+name);
	}

	@Override
	public void setEmbeddedValueResolver(StringValueResolver resolver) {
		String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");
		System.out.println("解析的字符串:"+resolveStringValue);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值