Understanding the Implementation Mechanism of Spring's @Autowired Annotation

This article explains how Spring processes the @Autowired annotation by detailing the related classes, bean post‑processor interfaces, bean creation lifecycle, metadata collection, and property injection steps, complete with code examples and diagrams for deeper insight.

Architecture Digest
Architecture Digest
Architecture Digest
Understanding the Implementation Mechanism of Spring's @Autowired Annotation

During an interview the author was asked about how Spring annotations work and responded by focusing on the @Autowired annotation, using it as a chance to demonstrate knowledge of its internal processing.

Interview technique advice is also given: avoid saying "I don't know" and steer the conversation toward familiar technologies.

@Autowired Related Classes

The core class that implements @Autowired functionality is AutowiredAnnotationBeanPostProcessor, which parses the annotation and performs automatic injection. Its inheritance hierarchy includes BeanPostProcessor, InstantiationAwareBeanPostProcessor, and MergedBeanDefinitionPostProcessor.

InstantiationAwareBeanPostProcessor Interface

Key methods:

postProcessBeforeInstantiation : called before bean instantiation; can return a bean instance (default returns null).

postProcessAfterInstantiation : called after bean creation but before property population; default returns true.

postProcessProperties : called before setting bean properties; default returns null.

@Nullable default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { return null; }
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { return true; }
@Nullable default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; }

MergedBeanDefinitionPostProcessor

This interface allows post‑processors to modify merged BeanDefinition objects. It defines two methods:

void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
void resetBeanDefinition(String beanName);

AutowireCapableBeanFactory Interface

Extends BeanFactory and provides automatic injection capabilities. It defines four injection models:

AUTOWIRE_NO – no explicit injection model.

AUTOWIRE_BY_NAME – inject by bean name.

AUTOWIRE_BY_TYPE – inject by bean type.

AUTOWIRE_CONSTRUCTOR – inject via constructor.

The interface also declares createBean(Class<T> beanClass), which is invoked during bean creation.

<T> T createBean(Class<T> beanClass) throws BeansException;

Bean Creation Lifecycle

Spring creates beans lazily. The process starts with getBean and proceeds through:

getBean

doGetBean

createBean

doCreateBean

populateBean

The crucial point for @Autowired is the createBean method in AbstractAutowireCapableBeanFactory, which eventually calls doCreateBean.

Collecting Injection Metadata

During bean creation,

AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition

is invoked, which calls findAutowiringMetadata and then buildAutowiringMetadata to create an InjectionMetadata object that is cached in injectionMetadataCache.

@Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); }
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) { String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { synchronized (this.injectionMetadataCache) { metadata = this.injectionMetadataCache.get(cacheKey); if (InjectionMetadata.needsRefresh(metadata, clazz)) { metadata = buildAutowiringMetadata(clazz); this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }

Setting Bean Properties

After metadata collection, populateBean is called, which invokes InstantiationAwareBeanPostProcessor.postProcessProperties. The AutowiredAnnotationBeanPostProcessor implementation retrieves the metadata and performs the actual injection.

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); ... if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); ... } } } }
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex); } return pvs; }

Conclusion

The article walks through the classes involved in processing @Autowired, the steps of collecting injection metadata, and the points where Spring injects dependencies into beans. By studying the source of AutowiredAnnotationBeanPostProcessor and related interfaces, readers can deepen their understanding of Spring's dependency injection mechanism and even customize it.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendAutowiredBeanPostProcessordependency-injection
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.