-
Notifications
You must be signed in to change notification settings - Fork 38.8k
Closed
Closed
Copy link
Labels
in: coreIssues in core modules (aop, beans, core, context, expression)Issues in core modules (aop, beans, core, context, expression)type: bugA general bugA general bug
Milestone
Description
version: v6.2.9
In DefaultListableBeanFactory.java will set this.mainThreadPrefix = null;
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
//
// 为了保证扫描的顺序和创建的顺序一直ArrayList单独存储名字 it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
List<CompletableFuture<?>> futures = new ArrayList<>();
this.preInstantiationThread.set(PreInstantiation.MAIN);
this.mainThreadPrefix = getThreadNamePrefix();
try {
for (String beanName : beanNames) {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
if (!mbd.isAbstract() && mbd.isSingleton()) {
CompletableFuture<?> future = preInstantiateSingleton(beanName, mbd);
// 存在异步创建bean
if (future != null) {
futures.add(future);
}
}
}
}
finally {
this.mainThreadPrefix = null;
this.preInstantiationThread.remove();
}
if (!futures.isEmpty()) {
try {
CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0])).join();
}
catch (CompletionException ex) {
ReflectionUtils.rethrowRuntimeException(ex.getCause());
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName, false);
if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
smartSingleton.afterSingletonsInstantiated();
smartInitialize.end();
}
}
}
Suppose I have multiple background beans:
@Component
public class BatchBeanDefinitionRegister implements BeanDefinitionRegistryPostProcessor{
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
for (int i=0;i<10;i++){
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(AService.class);
// spring6:
rootBeanDefinition.setBackgroundInit(true);
registry.registerBeanDefinition("AService"+i,rootBeanDefinition);
}
}
public class AService {
public AService() throws InterruptedException {
Thread.sleep(5000);
}
}
It takes not 5 seconds, but may take 10, 15, or 20 seconds, indicating that it will block synchronous creation.
But if I comment // this.mainThreadPrefix = null;
The time taken is 5 seconds, indicating asynchronous creation bean.
Metadata
Metadata
Assignees
Labels
in: coreIssues in core modules (aop, beans, core, context, expression)Issues in core modules (aop, beans, core, context, expression)type: bugA general bugA general bug