Skip to content

Commit

Permalink
Defensive singleton check for non-registered bean
Browse files Browse the repository at this point in the history
Closes gh-33286
  • Loading branch information
jhoeller committed Jul 29, 2024
1 parent 5aa3883 commit 9d9e621
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,9 @@ public Object postProcessAfterInitialization(Object bean, String beanName) {
logger.trace(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName +
"': " + annotatedMethods);
}
if ((this.beanFactory != null && !this.beanFactory.isSingleton(beanName)) ||
(this.beanFactory instanceof SingletonBeanRegistry sbr && sbr.containsSingleton(beanName))) {
if ((this.beanFactory != null &&
(!this.beanFactory.containsBean(beanName) || !this.beanFactory.isSingleton(beanName)) ||
(this.beanFactory instanceof SingletonBeanRegistry sbr && sbr.containsSingleton(beanName)))) {
// Either a prototype/scoped bean or a FactoryBean with a pre-existing managed singleton
// -> trigger manual cancellation when ContextClosedEvent comes in
this.manualCancellationOnContextClose.add(bean);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.junit.jupiter.api.AfterEach;
Expand Down Expand Up @@ -294,6 +295,24 @@ void oneTimeTask() {
assertThat(task.getInitialDelayDuration()).isEqualTo(Duration.ofMillis(2_000L));
}

@Test
void oneTimeTaskOnNonRegisteredBean() {
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
context.registerBeanDefinition("postProcessor", processorDefinition);
context.refresh();

ScheduledTaskHolder postProcessor = context.getBean("postProcessor", ScheduledTaskHolder.class);
assertThat(postProcessor.getScheduledTasks()).hasSize(0);

Object target = context.getAutowireCapableBeanFactory().createBean(OneTimeTaskBean.class);
assertThat(postProcessor.getScheduledTasks()).hasSize(1);
@SuppressWarnings("unchecked")
Set<Object> manualTasks = (Set<Object>)
new DirectFieldAccessor(postProcessor).getPropertyValue("manualCancellationOnContextClose");
assertThat(manualTasks).hasSize(1);
assertThat(manualTasks).contains(target);
}

@Test
void cronTask() {
BeanDefinition processorDefinition = new RootBeanDefinition(ScheduledAnnotationBeanPostProcessor.class);
Expand Down

0 comments on commit 9d9e621

Please sign in to comment.