SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?

@Value java doc文档指出,它是由AutowiredAnnotationBeanPostProcessor这个BeanPostProcessor处理的。
AutowiredAnnotationBeanPostProcessor的构造方法如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第1张图片
可见AutowiredAnnotationBeanPostProcessor用来处理@Autowired和@Value这两个注解。
具体的处理流程是通过在容器对bean进行实例化的时候应用上述BeanPostProcessor.

示例分析(以@Value为例):
controller类:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第2张图片
启动类:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第3张图片

完整流程如下:
主类运行main方法,运行到SpringApplication的静态run方法:
在这里插入图片描述
该方法调用了重载的run方法:
在这里插入图片描述
该方法首先创建出了一个SpringApplication对象,然后调用了该对象的run方法:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第4张图片
该run方法中调用了refreshContex方法:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第5张图片
refreshContext方法调用了refresh方法:
在这里插入图片描述
该方法又调用了applicationContext对象的refresh方法,此处的applicationContext的实际类型是ServletWebServerApplicationContext,所以调用的是ServletWebServerApplicationContext的refresh方法:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第6张图片
这个refresh方法调用了父类的refresh方法,也就是AbstractApplicationContext的refresh方法:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第7张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第8张图片
其中会调用finisheBeanFactoryInitialization方法,它的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第9张图片SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第10张图片
其中会调用preInstantiateSingletons方法,它的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第11张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第12张图片
preInstantiateSingletons这个方法会实例化所有的singleton的bean,
在实例化我自己定义的DemoController类的这个bean时,

其中调用的getBean方法代码如下(位于AbstractBeanFactory类):
在这里插入图片描述
其中调用的doGetBean方法代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第13张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第14张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第15张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第16张图片
然后会执行到上图中画线的getSingleton,因为此时demoController这个bean还不存在,所以,getSingleton执行过成中会调用lambda表达式中的createBean来创建democontroller bean, createBean的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第17张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第18张图片
其中调用了doCreateBean,它的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第19张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第20张图片

其中调用了populateBean,它的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第21张图片
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第22张图片
其中对容器中的BeanPostProcessor(AutowiredAnnotationBeanPostProcessor包含在其中)进行遍历,调用了postProcessProperties方法,AutowiredAnnotationBeanPostProcessor的postProcessProperties代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第23张图片
其中调用的inject方法代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第24张图片

其中调用的inject方法代码如下(位于AutowiredAnnotationBeanPostProcessor):
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第25张图片
可以看到这个方法首先拿到了要注入的值(value = resolveFieldValue(field, bean, beanName),然后利用反射给bean的属性设置了值(field.set(bean,value)).
resolveFiledValue的逻辑是什么呢?代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第26张图片
其中调用了beanFactory.resolveDependency方法,它的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第27张图片
其中调用了doResolveDependency,它的代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第28张图片
其中调用的resolveEmbededValue代码如下:
SpringBoot复习:(18)@Value和@Autowired注解配置的属性是怎么注入到bean中的?_第29张图片
在其中会遍历embeddedValueResolvers成员变量,用它所包含的StringValueResolver进行解析,最后把解析的结果返回。

你可能感兴趣的:(SpringBoot,spring,boot,java,后端)