Spring ④ Autowired 注解依赖注入详解 | 看不懂你打我
Spring 源码系列文章会遵循由浅入深,由易到难,由宏观到微观的原则,目标是尽量降低学习难度,而不是一上来就迷失在源码当中. 文章会从一个场景作为出发点,针对性的目的性极强的针对该场景对 Spring 的实现原理,源码进行探究学习。该系列文章会让你收获什么? 从对 Spring 的使用者成为 Spring 专家。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。
本章的内容是对 bean 创建过程中依赖项注入的探究,为了不扩散问题域本章只针对 @Autowired
注解进行讲解分析。本章会讲解 构造器注入
、属性注入
、方法注入
、Optional
、ObjectFactory
、ObjectProvider
、JSR330
类型的属性注入。方式遵循前几期,会通过最简单的案例场景带入去叫讲解 spring 的实现原理。
在开始今天的内容之前先回顾一下上期的内容, bean 的创建过程大致经历了三步,
createBeanInstance
创建 bean 的实例对象。populateBean
填充bean,依赖注入发生在这个阶段(大部分场景是,但一些特殊场景的依赖注入并不在这个阶段进行比如构造器注入)。initializeBean
进行 bean 的一些初始化过程。了解了这个 bean 创建的大致过程会对读者理解本期的内容起帮助作用。
构造器注入
构造器注入过程发生在 bean 对象的实例化阶段,是和对象的实例化同时进行的,因为是通过构造器注入 bean 的实例化过程也是通过构造器。
构造器注入场景
public class AutowiredConstructorInjectionExp {
public static void main(String[] args) {
// 构造器注入
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(factory);
factory.addBeanPostProcessor(processor);
factory.registerBeanDefinition("bean1" , BeanDefinitionBuilder
.genericBeanDefinition(Bean1.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean2" , BeanDefinitionBuilder
.genericBeanDefinition(Bean2.class)
.getBeanDefinition());
Bean1 bean1 = factory.getBean(Bean1.class);
System.out.println("bean1 -> " + bean1);
}
@Data
static class Bean1 {
Bean2 bean2;
public Bean1(Bean2 bean2) {
this.bean2 = bean2;
System.out.println("======================== bean1 实例化");
}
}
static class Bean2 {
public Bean2() {
System.out.println("++++++++++++++++++++++++++ bean2 实例化");
}
}
}
构造器注入 autowireConstructor
构造器注入的关键点在
determineConstructorsFromBeanPostProcessors
和autowireConstructor
. 接下来会着重探讨这两个方法。
determineConstructorsFromBeanPostProcessors
/**
* Determine candidate constructors to use for the given bean, checking all registered
* {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
* @param beanClass the raw class of the bean
* @param beanName the name of the bean
* @return the candidate constructors, or {@code null} if none specified
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
*/
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
在 determineConstructorsFromBeanPostProcessors
中调用了 SmartInstantiationAwareBeanPostProcessor
的 determineCandidateConstructors
方法。在场景代码中我们创建了 AutowiredAnnotationBeanPostProcessor
实例,并把它注册到 AbstractBeanFactory
中。这样就可以由它来起到探测构造器的功能。
determineConstructorsFromBeanPostProcessors
会得到多个构造器,autowireConstructor
会对这些构造器进行筛选找到一个合适匹配的构造器。
autowireConstructor
/**
* "autowire constructor" (with constructor arguments by type) behavior.
* Also applied if explicit constructor argument values are specified,
* matching all remaining arguments with beans from the bean factory.
* <p>This corresponds to constructor injection: In this mode, a Spring
* bean factory is able to host components that expect constructor-based
* dependency resolution.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param ctors the chosen candidate constructors
* @param explicitArgs argument values passed in programmatically via the getBean method,
* or {@code null} if none (implying the use of constructor argument values from bean definition)
* @return a BeanWrapper for the new instance
*/
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
由于
ConstructorResolver
方法autowireConstructor
源码较为繁琐就不进行逐一讲解,有兴趣的读者可以自己阅读源码。这里列出几个关键方法ConstructorResolver#createArgumentArray
,ConstructorResolver.resolveAutowiredArgument
,AutowireCapableBeanFactory#resolveDependency
,ConstructorResolver#instantiate
和说明简图方便读者阅读源码时有针对性的查看。
AutowiredAnnotationBeanPostProcessor
在讲解
属性注入
和方法注入
前我们先认识一下AutowiredAnnotationBeanPostProcessor
bean 后置处理器 ,@Autowired
注解之所以可以起作用就是因为它在背后提供支持。AutowiredAnnotationBeanPostProcessor
实现了很多的 bean 后置处理器接口,其中有一个方法InstantiationAwareBeanPostProcessor#postProcessProperties
我们会着重进行讲解,它是和依赖注入密不可分的。通过
AutowiredAnnotationBeanPostProcessor
完成依赖注入的都是发生在populateBean
阶段(也就是 bean 的填充阶段)。
属性注入和方法注入
属性注入和方法注入十分的类似可以放在一起讲解。
属性注入场景
public class AutowiredFieldInjectionExp {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(factory);
factory.addBeanPostProcessor(processor);
factory.registerBeanDefinition("bean1" , BeanDefinitionBuilder
.genericBeanDefinition(Bean1.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean2" , BeanDefinitionBuilder
.genericBeanDefinition(Bean2.class)
.getBeanDefinition());
Bean1 bean1 = factory.getBean(Bean1.class);
System.out.println("bean1 -> " + bean1);
}
@Data
static class Bean1 {
@Autowired
Bean2 bean2;
public Bean1() {
System.out.println("======================== bean1 实例化");
}
}
static class Bean2 {
public Bean2() {
System.out.println("++++++++++++++++++++++++++ bean2 实例化");
}
}
}
方法注入场景
public class AutowiredMethodInjectionExp {
public static void main(String[] args) {
// 方法注入
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(factory);
factory.addBeanPostProcessor(processor);
factory.registerBeanDefinition("bean1" , BeanDefinitionBuilder
.genericBeanDefinition(Bean1.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean2" , BeanDefinitionBuilder
.genericBeanDefinition(Bean2.class)
.getBeanDefinition());
Bean1 bean1 = factory.getBean(Bean1.class);
System.out.println("bean1 -> " + bean1);
}
@ToString
static class Bean1 {
Bean2 bean2;
@Autowired
public void setBean2(Bean2 bean2) {
this.bean2 = bean2;
}
}
static class Bean2 {
public Bean2() {
System.out.println("++++++++++++++++++++++++++ bean2 实例化");
}
}
}
对源码 debug 我们可以发现在执行
AutowiredAnnotationBeanPostProcessor#postProcessProperties
之前Bean1
中的bean2
属性为null
. 并且instantiationAware
中只有一个元素AutowiredAnnotationBeanPostProcessor
对象. 我们已经尽可能的排除了干扰.
在执行了
AutowiredAnnotationBeanPostProcessor#postProcessProperties
之后bean2
属性已经有值了. 接下来我们会重点看postProcessProperties
方法中都做了什么。
AutowiredAnnotationBeanPostProcessor#postProcessProperties
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
findAutowiringMetadata
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
InjectionMetadata#inject
不同的注入元素有不同的注入方式实现,
属性注入
为AutowiredFieldElement
,方法注入
为AutowiredMethodElement
.
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
AutowiredFieldElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
AutowiredMethodElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
try {
arguments = resolveCachedArguments(beanName);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
Optional
、ObjectFactory
、ObjectProvider
、JSR330
类型的注入
由于这部分较为简单容易理解就只做简单介绍。其中
ObjectFactory
、ObjectProvider
、JSR330
这三类其实是起到了延迟加载的作用。核心代码在org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
方法。
场景
public class AutowiredOtherTypeInjectionExp {
public static void main(String[] args) {
// `Optional` 、`ObjectFactory` 、`ObjectProvider` 、`JSR330` 类型的注入
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(factory);
factory.addBeanPostProcessor(processor);
factory.registerBeanDefinition("bean1" , BeanDefinitionBuilder
.genericBeanDefinition(Bean1.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean2" , BeanDefinitionBuilder
.genericBeanDefinition(Bean2.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean3" , BeanDefinitionBuilder
.genericBeanDefinition(Bean3.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean4" , BeanDefinitionBuilder
.genericBeanDefinition(Bean4.class)
.getBeanDefinition());
factory.registerBeanDefinition("bean5" , BeanDefinitionBuilder
.genericBeanDefinition(Bean5.class)
.getBeanDefinition());
Bean1 bean1 = factory.getBean(Bean1.class);
System.out.println("bean1 -> " + bean1);
}
@Data
static class Bean1 {
@Autowired
Optional<Bean2> bean2;
@Autowired
ObjectFactory<Bean3> bean3;
@Autowired
ObjectProvider<Bean4> bean4;
@Autowired
Provider<Bean5> bean5;
public Bean1() {
System.out.println("======================== bean1 实例化");
}
}
static class Bean2 {
public Bean2() {
System.out.println("++++++++++++++++++++++++++ bean2 实例化");
}
}
static class Bean3 {
public Bean3() {
System.out.println("++++++++++++++++++++++++++ Bean3 实例化");
}
}
static class Bean4 {
public Bean4() {
System.out.println("++++++++++++++++++++++++++ Bean4 实例化");
}
}
static class Bean5 {
public Bean5() {
System.out.println("++++++++++++++++++++++++++ Bean5 实例化");
}
}
}
DefaultListableBeanFactory#resolveDependency
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
@Autowired 注解实现依赖注入的原理和过程基本介绍完毕,更详细的细节过程以及源码会在系列文章的后续内容中提供。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。