依赖注入(DI)是Spring核心特性之一,而@Autowired也是我们日常高频使用的Spring依赖注入方式之一,因此有必要对它的使用以及原理做一个全面的掌握。本文从@Autowired使用、原理入手记录,并扩展延伸Spring中其他具备注入功能的注解。
我们直接通Autowired注解源码来看下该注解的简介
// 可以标注在构造器、方法、参数、字段、注解类型(做为元注解)上 @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) // 运行时注解 @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Autowired { /** * Declares whether the annotated dependency is required. * 声明该注解标注的依赖是否需要一定存在于Spring容器中 * true为必须存在,如果不存在的话就抛出NoSuchBeanDefinitionException异常 * false不要求必须存在,如果不存在也不抛出异常(一般不建议设置,可能会引发线上事故) *Defaults to {@code true}. */ boolean required() default true; }
通过上面代码我们可以看出@Autowired可以标注在构造器、方法、参数、字段以及派生注解上,所以注入时机非常多,可以准确的控制在何时、何处注入以及如何注入。
我们先来学习下关于@Autowired的使用方式:
Bean配置类
public class BeanConfiguration { @Bean public User user() { return new User("markus", 24); } }
演示类
package com.markus.spring.injection; import com.markus.spring.annotation.MyAutowired; import com.markus.spring.bean.User; import com.markus.spring.configuration.BeanConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import java.util.Collection; import java.util.Map; /** * @author: markus * @date: 2023/2/5 10:43 PM * @Description: @Autowired注解示例 * @Blog: https://markuszhang.com * It's my honor to share what I've learned with you! */ // 导入Bean配置 @Import({ com.markus.spring.configuration.BeanConfiguration.class }) public class AutowiredAnnotationDependencyInjectionDemo { @Autowired private User user; @Autowired private MapuserMap; @Autowired private Collection userCollection; private User userFromCtor; // @Autowired 可标注在构造器或者构造器的参数里面,两者取其一即可 public AutowiredAnnotationDependencyInjectionDemo(@Autowired User user) { this.userFromCtor = user; } private User userFromMethod; @Autowired public void autowiredUser(User user) { this.userFromMethod = user; } @MyAutowired private User userFromCustomAnnotation; public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(AutowiredAnnotationDependencyInjectionDemo.class); context.refresh(); AutowiredAnnotationDependencyInjectionDemo demo = context.getBean(AutowiredAnnotationDependencyInjectionDemo.class); System.out.println("demo.user : " + demo.user); System.out.println("demo.userMap : " +demo.userMap); System.out.println("demo.userCollection : " +demo.userCollection); System.out.println("demo.userFromCtor : " +demo.userFromCtor); System.out.println("demo.userFromMethod : " +demo.userFromMethod); System.out.println("demo.userFromCustomAnnotation : " +demo.userFromCustomAnnotation); context.close(); } }
控制台结果
当Spring容器中有多个相同类型的Bean时,它还可以与@Qualifier配合使用来指定某一特定的Bean
Bean配置
/** * @author: markus * @date: 2023/2/11 4:49 PM * @Description: 相同类型多个Bean配置 * @Blog: https://markuszhang.com * It's my honor to share what I've learned with you! */ public class SameTypeBeanConfiguration { @Bean public User user1() { return new User("markus", 24); } @Bean public User user2() { return new User("Luna", 23); } }
演示类
package com.markus.spring.injection; import com.markus.spring.bean.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Import; /** * @author: markus * @date: 2023/2/11 4:47 PM * @Description: * @Blog: https://markuszhang.com * It's my honor to share what I've learned with you! */ @Import({ com.markus.spring.configuration.SameTypeBeanConfiguration.class }) public class QualifierAnnotationUseDemo { @Autowired @Qualifier(value = "user1") private User user; public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(QualifierAnnotationUseDemo.class); context.refresh(); QualifierAnnotationUseDemo demo = context.getBean(QualifierAnnotationUseDemo.class); System.out.println("demo.user : " + demo.user); context.close(); } }
控制台
在讲解@Autowired原理之前,有必要先提及一下Bean的生命周期,但在这里不做过多叙述,只是让大家有个大致的认识,以及@Autowired在哪里开始发挥作用的。
上图为Spring Bean的整个的一个生命周期,包括定义Bean配置信息、加载解析并注册Bean元信息,在我们程序运行时getBean获取Spring Bean又会经过Bean的实例化、属性赋值、初始化等环节,在这些环节前后,Spring也给了我们一些扩展机会,例如实例化前后、属性赋值前、初始化前、初始化后。因为Spring 单例Bean的生命周期是交给容器去管理的,所以Bean的销毁最后也依赖于容器的销毁,当容器发出销毁消息时,会触发Bean的销毁逻辑,这是我们也可以在Bean销毁前做一些自定义操作。至此就是关于Spring Bean生命周期的一个大体介绍。
那么@Autowired到底发生在哪个阶段呢?我们接下来再来分析下BeanFactory#getBean的内部大致流程!
上图中标红的备注中正是@Autowired发挥作用的环节。Bean生命周期后续会单独写一篇文章,这里就不做展开了,我们把关注点聚焦到@Autowired实现细节上去!
通过Bean生命周期概览,我们知道如果想要挖掘@Autowired实现的原理,我们先要去了解两个类:
- AbstractAutowiredCapableBeanFactory
- AutowiredAnnotationBeanPostProcessor
我们通过IDEA定位到AbstractAutowiredCapableBeanFactory这个类的doCreateBean方法,在这个方法里面我们关注两个函数:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { // xxx } } try { populateBean(beanName, mbd, instanceWrapper); } catch (Throwable ex) { // xxx } return exposedObject; }
通过doCreateBean函数进入到applyMergedBeanDefinitionPostProcessors方法,来看看其内部做了哪些事情:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
返回到doCreateBean函数并进入到populateBean方法,抛出非核心的代码逻辑,我们可以看到该函数内部一共有四大核心逻辑处理:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); pvs = pvsToUse; } } } if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
通过Bean生命周期概览,我们可以知道@Autowired是在Bean属性赋值阶段将依赖Bean注入到当前Bean字段中的,实现类是AutowiredAnnotationBeanPostProcessor,我们先来了解下它的继承结构并解释它的相关功能
看到上图的继承结构可以发现其实AutowiredAnnotationBeanPostProcessor具备两方面的功能,一方面是InstantiationAwareBeanPostProcessor在Bean实例化前后以及属性赋值前做些扩展;另一方面是在合并BeanDefinition后做些扩展,所谓“合并BeanDefinition”就是将配置的子BeanDefinition和父BeanDefinition合并形成当前Bean的最终BeanDefinition配置元信息,这里给大家举个具体例子:
我们先来看下AutowiredAnnotationBeanPostProcessor的构造器,可以看出它是@Autowired、@Value以及jsr-330的@Inject注解的实现,我们本节主要分析@Autowired注解的实现原理。
public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Value.class); try { this.autowiredAnnotationTypes.add((Class extends Annotation>) ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }
接下来就是@Autowired的核心逻辑,两个方法:
首先我们先来看下注入元信息内容是什么:
public class InjectionMetadata { // 目标类 private final Class> targetClass; // 注入元素 方法注入、字段注入 private final CollectioninjectedElements; @Nullable private volatile Set checkedElements; } public abstract static class InjectedElement { protected final Member member; protected final boolean isField; // 这是核心方法,后续会涉及到,它是字段注入或者是方法注入的最终环节 protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable { if (this.isField) { Field field = (Field) this.member; ReflectionUtils.makeAccessible(field); field.set(target, getResourceToInject(target, requestingBeanName)); } else { if (checkPropertySkipping(pvs)) { return; } try { Method method = (Method) this.member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } }
再来看下postProcessorMergedBeanDefinition方法
@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) { // 1.构建注入元信息 InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); } private InjectionMetadata findAutowiringMetadata(String beanName, Class> clazz, @Nullable PropertyValues pvs) { // 1.1 构建缓存key String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // 1.2 先从注解元信息缓存中获取,如果能获取到直接返回 InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); // 1.3 需要刷新注解元信息,两种情况:一种是元信息为空;另一种是元信息缓存类型与当前类型不匹配 if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { if (metadata != null) { metadata.clear(pvs); } // 1.4 真正构建注解元信息的逻辑 metadata = buildAutowiringMetadata(clazz); // 1.5 将注解元信息存储到缓存中 this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; } // 1.4.1 在构建注解元信息有两个方法:一种是查找被@Autowired注解标注的字段;另一种是查找被@Autowired注解标注的方法 // 下面整个方法都是围绕这两个方面来开展的 private InjectionMetadata buildAutowiringMetadata(final Class> clazz) { if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; } Listelements = new ArrayList<>(); Class> targetClass = clazz; do { final List 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); }
接着再来看下postProcessProperties方法,逻辑很简单,就两步:
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { // 2.1 查找注入元信息内部逻辑比较简单,不做展开了。就是通过去缓存中查找,如果找不到就重新构建一遍,否则就返回缓存中的信息 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // 2.2 进行注入,这里面的逻辑就比较复杂了,接下来我们主要围绕该方法来讲解流程 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; }
前面我们说到@Autowired的注入流程首先是需要构建一个InjectionMetadata,并通过InjectionMetadata的inject方法来进行注入,所以我们通过下图来熟悉下它的核心依赖项
下面再通过源码来直观解释下上图:
public class InjectionMetadata { // <1> 该函数的作用是,将候选注入集依次遍历进行注入 public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { CollectioncheckedElements = this.checkedElements; Collection elementsToIterate = (checkedElements != null ? checkedElements : this.injectedElements); if (!elementsToIterate.isEmpty()) { for (InjectedElement element : elementsToIterate) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } // <1.1>真正实现注入的函数 element.inject(target, beanName, pvs); } } } } public abstract static class InjectedElement { /** * 这个方法由子类重写 */ protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs) throws Throwable { if (this.isField) { Field field = (Field) this.member; ReflectionUtils.makeAccessible(field); field.set(target, getResourceToInject(target, requestingBeanName)); } else { if (checkPropertySkipping(pvs)) { return; } try { Method method = (Method) this.member; ReflectionUtils.makeAccessible(method); method.invoke(target, getResourceToInject(target, requestingBeanName)); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } } } private class AutowiredFieldElement extends InjectionMetadata.InjectedElement { // 字段注入的核心实现 @Override protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; if (this.cached) { // <2.1> 利用缓存快速返回 value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { // <2.2> 获取指定beanName依赖 value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } // <2.3> 缓存优化 synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { // <2.4> 通过反射实现字段赋值 ReflectionUtils.makeAccessible(field); field.set(bean, value); } } } private class AutowiredMethodElement extends InjectionMetadata.InjectedElement { // <3.1> 方法注入的核心实现 @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) { // Shortcut for avoiding synchronization... arguments = resolveCachedArguments(beanName); } else { int argumentCount = method.getParameterCount(); arguments = new Object[argumentCount]; DependencyDescriptor[] descriptors = new DependencyDescriptor[argumentCount]; Set autowiredBeans = new LinkedHashSet<>(argumentCount); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); // <3.2> 根据当前方法的参数,遍历依次获取相应参数依赖,然后最终进行注入 for (int i = 0; i < arguments.length; i++) { MethodParameter methodParam = new MethodParameter(method, i); DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required); currDesc.setContainingClass(bean.getClass()); descriptors[i] = currDesc; try { // <3.2.1> 获取指定beanName的依赖对象 Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter); if (arg == null && !this.required) { arguments = null; break; } arguments[i] = arg; } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex); } } // <3.3> 缓存优化 synchronized (this) { if (!this.cached) { if (arguments != null) { DependencyDescriptor[] cachedMethodArguments = Arrays.copyOf(descriptors, arguments.length); registerDependentBeans(beanName, autowiredBeans); if (autowiredBeans.size() == argumentCount) { Iterator it = autowiredBeans.iterator(); Class>[] paramTypes = method.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { String autowiredBeanName = it.next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) { cachedMethodArguments[i] = new ShortcutDependencyDescriptor( descriptors[i], autowiredBeanName, paramTypes[i]); } } } this.cachedMethodArguments = cachedMethodArguments; } else { this.cachedMethodArguments = null; } this.cached = true; } } } if (arguments != null) { try { // <3.4> 通过反射实现方法调用实现依赖注入 ReflectionUtils.makeAccessible(method); method.invoke(bean, arguments); } catch (InvocationTargetException ex) { throw ex.getTargetException(); } } }
通过上面一连串的代码,我们得出一个结论:
- 目标对象通过反射的方式进行字段setter方法赋值或者方法调用进行注入
- 目标依赖是通过DefaultListableBeanFactory的resolveDependency方法获取
通过反射调用进行属性赋值或者方法执行这块比较简单,也不赘述了,接下来就开始分析下DefaultListableBeanFactory#resolveDependency的内部流程,这要是@Autowired注解实现原理最核心的一块了。下面我还是通过代码注释的方式进行叙述
@Override @Nullable public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, @Nullable SetautowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); // <1> 如果依赖对象类型是Optional,则将依赖强转为Optional类型返回 if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } // <2> 如果ObjectFactory或者ObjectProvider类型的,则转换为对应类型返回 // ObjectFactory和ObjectProvider都是对象工厂,支持延迟加载,前者不包含泛型,后者支持泛型 else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider(descriptor, requestingBeanName); } // <3> jsr-330规范 else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName); } else { // <4.1> 目标依赖对象是否是延迟加载,如果延迟加载,则构造相应代理返回 Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary( descriptor, requestingBeanName); if (result == null) { // <4.2> 一般情况下都会走到这个流程下,解析依赖的一般流程,我们进入详细看下 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); } // 最后将对象返回 return result; } } @Nullable public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { // 设置当前注入点 ps 似乎没什么用,我目前没有发现它的作用是什么。 InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { // 删除部分不重要的代码 // ... // 获取@Value的配置值 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { // 下面一段代码就是将@Value获取的配置的值,转换成相应类型的值。TypeConverter就是类型转换器 if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); try { return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor()); } catch (UnsupportedOperationException ex) { // A custom TypeConverter which does not support TypeDescriptor resolution... return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } } // 解析多Bean的情况,例如被注入的字段为集合、Map、流等 // 进入该方法内部,可以看到它支持一下类型的注入:Stream
我们在原理这一节罗列了大量的代码,乍一看上去可能有些乱,所以在这里我给大家理顺一下思路:
以上就是我对@Autowired注解实现原理的理解,下面再来介绍下其他注解的使用,例如@Resource,@Value(基本类似,就不做罗列了)
package com.markus.spring.injection; import com.markus.spring.bean.User; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Import; import javax.annotation.Resource; import java.util.List; /** * @author: markus * @date: 2023/2/12 10:33 PM * @Description: @Resource注解使用 * @Blog: https://markuszhang.com * It's my honor to share what I've learned with you! */ @Import({ com.markus.spring.configuration.SameTypeBeanConfiguration.class }) public class ResourceAnnotationDependencyInjectionDemo { @Resource private Listusers; @Resource private User user; @Resource(name = "user2") private User userFromName; public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(ResourceAnnotationDependencyInjectionDemo.class); context.refresh(); ResourceAnnotationDependencyInjectionDemo demo = context.getBean(ResourceAnnotationDependencyInjectionDemo.class); System.out.println("demo.users : " + demo.users); System.out.println("demo.user : " + demo.user); System.out.println("demo.userFromName : " + demo.userFromName); } }
控制台
原理就不做展开了,这里就简单介绍@Resource与@Autowired的区别以及如何看@Resource的源码
先来看下@Autowired的
再来看下Resource的
本章介绍了@Autowired注解的使用、原理(几个核心类的关键方法)、同功能其他注解的演示(@Resource)并且比较了两者的区别。
读到这里,关于@Autowired的使用以及注入原理相信大家都有了比较充分的了解。
如果有不明白的地方或者我表述不准确的地方,欢迎评论区沟通交流!🤝
上一篇:【数据库管理】⑩数据字典