How Does Spring’s MergedBeanDefinitionPostProcessor Work? A Deep Dive
This article explains the role of Spring's MergedBeanDefinitionPostProcessor, showing how it merges bean definitions, invokes post‑processors during bean creation, and enables @Autowired‑related dependency injection with code examples and detailed workflow steps.
Environment
Spring Boot 2.3.12 RELEASE.
Purpose of MergedBeanDefinitionPostProcessor
The MergedBeanDefinitionPostProcessor merges bean definitions and allows post‑processors to modify them after the bean instance is created.
1. Setup Example
@Component
public class PersonDAOImpl implements PersonDAO {
@Override
public void save() {
System.out.println("保存Person信息");
}
}
@Service
public class UsersService {
@Autowired
private PersonDAO personDAO;
public void saveUsers(Users users) {
System.out.println("保存用户信息");
}
}2. Bean Creation
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Allow post‑processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// invoke MergedBeanDefinitionPostProcessor after instance creation
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
}
mbd.postProcessed = true;
}
}
}3. Applying Merged Bean Definition Processors
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
((MergedBeanDefinitionPostProcessor) bp)
.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}The relevant BeanPostProcessor implementations are CommonAnnotationBeanPostProcessor (handles @PostConstruct, @PreDestroy, @Resource) and AutowiredAnnotationBeanPostProcessor (handles @Autowired, @Value, @Inject).
4. AutowiredAnnotationBeanPostProcessor Core Logic
public class AutowiredAnnotationBeanPostProcessor {
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", getClass().getClassLoader()));
} catch (ClassNotFoundException ex) {
// JSR‑330 not available
}
}
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)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
// buildAutowiringMetadata scans fields and methods for @Autowired, @Value, @Inject
}5. Property Injection
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
metadata.inject(bean, beanName, pvs);
return pvs;
}Through these steps, Spring’s MergedBeanDefinitionPostProcessor enables the framework to resolve @Autowired and related annotations, cache metadata, and inject dependencies during bean creation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
