Spring依赖注入之@autowire注解详解

目录

@autowire用法

@autowire注解底层逻辑

逻辑处理类AutowiredAnnotationBeanPostProcessor

postProcessMergedBeanDefinition获取注入点

postProcessProperties针对注入点字段或者方法获取bean

字段注入

set方法注入


@autowire用法

  • 属性上:先根据属性类型去找Bean,如果找到多个再根据属性名确定一个
@Component
public class A {
	@Autowired
	private B b;
}
  • 构造方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个
@Component
public class A {

	private B b;

	@Autowired
	public A(B b) {
		this.b = b;
	}
}
  • set方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定一个
@Component
public class A {

	private B b;

	public B getB() {
		return b;
	}
	@Autowired
	public void setB(B b) {
		this.b = b;
	}
}

@autowire注解底层逻辑

它主要逻辑处理类AutowiredAnnotationBeanPostProcessor

逻辑处理类AutowiredAnnotationBeanPostProcessor

这个类实现了SmartInstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor,

重写了MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition和

SmartInstantiationAwareBeanPostProcessor.postProcessProperties方法

public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
		MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {

这两个拓展点均参与了bean生命周期,postProcessMergedBeanDefinition在实例化后执行,postProcessProperties在属性注入时执行

postProcessMergedBeanDefinition获取注入点

主要的作用获取所有方法和字段中@autowire的注入点放到缓存injectionMetadataCache中;
遍历当前类的所有的属性字段Field
查看字段上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该字段是一个注入点
如果字段是static的,则不进行注入,获取@Autowired中的required属性的值,将字段信息构造成一个AutowiredFieldElement对象,作为一个注入点对象添加到currElements集合中。
遍历当前类的所有方法Method,判断当前Method是否是桥接方法,如果是找到原方法,查看方法上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该方法,是一个注入点
如果方法是static的,则不进行注入,获取@Autowired中的required属性的值,将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到currElements集合中。
遍历完当前类的字段和方法后,将遍历父类的,直到没有父类。最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对于的注入点集合对象,并缓存。

postProcessProperties针对注入点字段或者方法获取bean

字段注入


1遍历所有的AutowiredFieldElement对象
2.将对应的字段封装为DependencyDescriptor对象

3.调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前字段所匹配的Bean对象。
4.将DependencyDescriptor对象和所找到的结果对象beanName封装成一个,ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了
5.利用反射将结果对象赋值给字段。

set方法注入


1遍历所有的AutowiredMethodElement对象
2.遍历将对应的方法的参数,将每个参数封装成MethodParameter对象
3.将MethodParameter对象封装为DependencyDescriptor对象
4.调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,
进行依赖查找,找到当前方法参数所匹配的Bean对象。
5.将DependencyDescriptor对象和所找到的结果对象beanName封装成一个ShortcutDependencyDescriptor对象作为缓存,比如如果当前Bean是原型Bean,那么下次再来创建该Bean时,就可以直接拿缓存的结果对象beanName去BeanFactory中去那bean对象了,不用再次进行查找了
6.利用反射将找到的所有结果对象传给当前方法,并执行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值