在spring项目中,我们经常会使用@Value注解,这个注解的作用就是把配置文件中配置的常量值赋值给@Value注解对应的属性。
这里我们可以来看一下源码,看看@Value是如何注入值的。
从AbstractAutowireCapableBeanFactory开始,这里会调用populateBean()方法。
接着又会调用AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues()方法。
继续执行,调用InjectionMetadata类的inject()方法,这里的checkedElements存放的就是需要注入的属性信息
继续执行,调用DefaultListableBeanFactory的doResolveDependency()方法。
在doResolveDependency()方法里面会调用resolveEmbeddedValue()方法。
接着执行到了AbstractBeanFactory的方法中,这里会调用PropertySourcesPlaceholderConfigurer的resolveStringValue()方法,这里是使用了一个匿名内部类。这一步在之前就已经执初始化过了,此时只是来执行里面的实现方法。
接下来执行的是propertyResolver.resolveRequiredPlaceholders()。
接着就执行到了PropertyPlaceholderHelper类中。这里placeholderResolver.resolvePlaceholder(placeholder)又会执行到前面定义的匿名内部类中,也就是执行getPropertyAsRawString()方法。这里的placeholder就是我们需要获取的key的名称。
由于getPropertyAsRawString()方法是一个abstract方法,所以也会执行它的实现方法,也就是PropertySourcesPropertyResolver类中的getPropertyAsRawString()方法。接着执行getProperty()方法。
接着会执行PropertySourcesPlaceholderConfigurer类中的getProperty()方法。我们发现这也是一个匿名内部类。在前面已经定义过了,现在直接执行里面的实现方法。
跟踪这个方法,执行到了PropertySourcesPropertyResolver类中的getProperty方法,然后又执行到了前面的getProperty()方法。此时,我们发现this.propertySources里面的内容要比之前多一些了,而且它还包含有读取application.yml配置文件的值。这其实是在前面就已经加载过了的。现在在这里获取我们传过来的key的值,就方便多了。
获取到key后就返回到前面提到的parseStringValue()方法继续执行。然后最终返回该key对应的value。
执行完成后,接着返回到DefaultListableBeanFactory的resolveEmbeddedValue()方法,这里会调用evaluateBeanDefinitionString()处理Expression表达式的值,最终返回我们需要的结果。
最后将结果返回到AutowiredAnnotationBeanPostProcessor类中,然后通过反射将值注入到我们bean相对应的属性中。这样就完成了@Value在bean中的值的注入过程。