寻找注入点
在创建一个Bean的过程中,Spring会利用AutowiredAnnotationBeanPostProcessor的**postProcessMergedBeanDefinition()**找出注入点并缓存,找注入点的流程为:
1、遍历当前类的所有的属性字段Field
2、字段上存在@Autowired、@Value、@Inject中的任意一个,就认为该字段是一个注入点
3、如果字段是static的,则不进行注入
4、获取@Autowired中的required属性的值
5、将字段信息构造成一个AutowiredFieldElement对象 ,作为一个注入点对象添加到currElements集合中
6、遍历当前类的所有方法Method
7、判断当前Method是否是桥接方法,如果是找到原方法
找到原方法后重复上面的2-5步
8、遍历完当前类的字段和方法后,再遍历父类的,直到没有父类。
9、最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对应的注入点集合对象并缓存。
static的字段或方法为什么不支持
static修饰的字段和方法是属于类的,在多例Bean的情况下很可能发生覆盖,相互影响导致错误发生
桥接方法
java
// 接口、泛型
public interface UserInterface<T>
{
void setOrderService(T t);
}
@Component
public class UserService implements UserInterface<OrderService>
{
private OrderService orderService;
@Override
@Autowired
public void setOrderService(OrderService orderService)
{
this.orderService = orderService;
}
}
在Spring中当遍历到桥接方法时,得找到原方法
注入点进行注入
Spring在AutowiredAnnotationBeanPostProcessor的**postProcessProperties()**方法中,会遍历所找到的注入点依次进行注入。
字段注入
1、遍历所有的AutowiredFieldElement对象
2、将对应的字段封装为DependencyDescriptor对象
3、调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前字段所匹配的Bean对象
4、将DependencyDescriptor对象 和所找到的结果对象beanName 封装成一个ShortcutDependencyDescriptor对象作为缓存
5、利用反射将结果对象赋值给字段
Set方法注入
1、遍历所有的AutowiredFieldElement对象
2、遍历将对应的方法的参数,将每个参数封装成MethodParameter对象
3、将MethodParameter对象 封装为DependencyDescriptor对象
4、调用BeanFactory的resolveDependency()方法,传入DependencyDescriptor对象,进行依赖查找,找到当前方法参数所匹配的Bean对象
5、将DependencyDescriptor对象 和所找到的结果对象beanName 封装成一个ShortcutDependencyDescriptor对象作为缓存
6、利用反射将找到的所有结果对象传给当前方法,并执行
待续...