关于@Autowired这个注解,咱们再熟悉不过了,常常跟@Resource来作对比,这篇文章咱们不讨论二者有何异同,仅分析@Autowired的原理(基于Spring5)。java
假如一个接口(IUserService)有两个实现类,分别是(UserServiceImpl01)和(UserServiceImpl02),在咱们给类注入的时候,这样写(@Autowired private IUserService userService)会发生什么状况?答案确定是报错,那么原理呢?文字描述:由于首先@Autowired是按照类型注入的,也就是.class,但UserServiceImpl01和UserServiceImpl02都是IUserService类型的,因而Spring就会按照后面的名字(userService)在容器中查找,但发现根本没有这个名字,由于两个实现类在不指定名字状况下,就是首字母小写的类名,而后抛出异常:expected single matching bean but found 2。。。app
还有不少种方法,但基本思想都同样,无非就是如何区分两个同祖宗的儿子,既然根儿相同,那就只有指定名字了。源码分析
提到@Autowired咱们通常都知道叫依赖注入post
依赖注入:Dependency Injection,简称DI,说白了就是利用反射机制为类的属性赋值的操做。this
注入就是为某个对象的外部资源赋值,注入某个对象所须要的外部资源(包括对象、资源、常量数据等)。IOC容器注入应用程序某个对象,应用程序所依赖的对象。spa
在完成对象的建立,为对象变量进行赋值的时候进行注入(populate)。debug
可见它间接实现InstantiationAwareBeanPostProcessor,就具有了实例化先后(而不是初始化先后)管理对象的能力,实现了BeanPostProcessor,具备初始化先后管理对象的能力,实现BeanFactoryAware,具有随时拿到BeanFactory的能力,也就是说,这个AutowiredAnnotationBeanPostProcessor具有一切后置处理器的能力。对象
首先找到须要注入的哪些元数据,而后metadata.inject(注入),注入方法点进去,来到InjectionMetadata的inject方法,在一个for循环里面依次执行element.inject(target, beanName, pvs),来对属性进行注入。blog
第584行,value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter),由工厂解析这个依赖,进入,来到DefaultListableBeanFactory第1065行,result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter)再次解析依赖,点击进入,来到DefaultListableBeanFactory的doResolveDependency()方法,前面是一堆判断,比较,查看属性类型,这种类型的有几个(matchingBeans),若是只有一个匹配,那么来到第1138行,instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this),进入这个方法,能够看到就是前面说的根据工厂来建立实例的过程了:beanFactory.getBean(beanName),其中这个beanName就是属性的名称,当通过一系列操做完成属性的实例化后,便来到AutowiredAnnotationBeanPostProcessor的第611行,利用反射为此对象赋值。这样,对象的建立以及赋值就完成了。继承
在容器启动,为对象赋值的时候,遇到@Autowired注解,会用后置处理器机制,来建立属性的实例,而后再利用反射机制,将实例化好的属性,赋值给对象上,这就是Autowired的原理。