diff --git a/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java index 85da53b39b0..88728844bf9 100644 --- a/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.context.support; import java.io.IOException; import java.lang.reflect.Constructor; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; @@ -423,16 +424,37 @@ public class GenericApplicationContext extends AbstractApplicationContext implem PostProcessorRegistrationDelegate.loadBeanPostProcessors( this.beanFactory, SmartInstantiationAwareBeanPostProcessor.class); + List lazyBeans = new ArrayList<>(); + + // First round: non-lazy singleton beans in definition order, + // matching preInstantiateSingletons. for (String beanName : this.beanFactory.getBeanDefinitionNames()) { - Class beanType = this.beanFactory.getType(beanName); - if (beanType != null) { - ClassHintUtils.registerProxyIfNecessary(beanType, runtimeHints); - for (SmartInstantiationAwareBeanPostProcessor bpp : bpps) { - Class newBeanType = bpp.determineBeanType(beanType, beanName); - if (newBeanType != beanType) { - ClassHintUtils.registerProxyIfNecessary(newBeanType, runtimeHints); - beanType = newBeanType; - } + BeanDefinition bd = getBeanDefinition(beanName); + if (bd.isSingleton() && !bd.isLazyInit()) { + preDetermineBeanType(beanName, bpps, runtimeHints); + } + else { + lazyBeans.add(beanName); + } + } + + // Second round: lazy singleton beans and scoped beans. + for (String beanName : lazyBeans) { + preDetermineBeanType(beanName, bpps, runtimeHints); + } + } + + private void preDetermineBeanType(String beanName, List bpps, + RuntimeHints runtimeHints) { + + Class beanType = this.beanFactory.getType(beanName); + if (beanType != null) { + ClassHintUtils.registerProxyIfNecessary(beanType, runtimeHints); + for (SmartInstantiationAwareBeanPostProcessor bpp : bpps) { + Class newBeanType = bpp.determineBeanType(beanType, beanName); + if (newBeanType != beanType) { + ClassHintUtils.registerProxyIfNecessary(newBeanType, runtimeHints); + beanType = newBeanType; } } }