-
Notifications
You must be signed in to change notification settings - Fork 38.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Private init/destroy method may be invoked twice #28083
Comments
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
@mroccyen thanks but please do not share screenshots as it bloats the issue report. I've hidden those for now. |
Sorry, I'll pay attention next time. Excuse me, is it correct for me to fix it like that above? |
I haven't investigated this in detail so I can't say for sure. |
I reproduced the described behavior with the following test class. @SpringJUnitConfig
class InitMethodTests {
@Test
@DirtiesContext
void test() {
assertSoftly(softly -> {
softly.assertThat(PublicLifecycleMethodBean.initCounter).as("public init-method").hasValue(1);
softly.assertThat(PrivateLifecycleMethodBean.initCounter).as("private init-method").hasValue(1);
});
}
@AfterAll
static void afterAll() {
assertSoftly(softly -> {
softly.assertThat(PublicLifecycleMethodBean.destroyCounter).as("public destroy-method").hasValue(1);
softly.assertThat(PrivateLifecycleMethodBean.destroyCounter).as("private destroy-method").hasValue(1);
});
}
@Configuration
static class Config {
@Bean(initMethod = "publicInit", destroyMethod = "publicDestroy")
Object publicLifecycleMethodBean() {
return new PublicLifecycleMethodBean();
}
@Bean(initMethod = "privateInit", destroyMethod = "privateDestroy")
Object privateLifecycleMethodBean() {
return new PrivateLifecycleMethodBean();
}
}
static class PublicLifecycleMethodBean {
static final AtomicInteger initCounter = new AtomicInteger();
static final AtomicInteger destroyCounter = new AtomicInteger();
@PostConstruct
public void publicInit() {
initCounter.incrementAndGet();
}
@PreDestroy
public void publicDestroy() {
destroyCounter.incrementAndGet();
}
}
static class PrivateLifecycleMethodBean {
static final AtomicInteger initCounter = new AtomicInteger();
static final AtomicInteger destroyCounter = new AtomicInteger();
@PostConstruct
private void privateInit() {
initCounter.incrementAndGet();
}
@PreDestroy
private void privateDestroy() {
destroyCounter.incrementAndGet();
}
}
} The "private init-method" and "private destroy-method" assertions fail due to 2 invocations. |
Superseded by #28113 |
Related Issues |
No, that would constitute a breaking change in behavior for We have decided to approach the fix differently, and I have therefore assigned this issue to myself. |
This commit introduces Javadoc to explain the difference between init/destroy method names when such methods are private, namely that a private method is registered via its qualified method name; whereas, a non-private method is registered via its simple name. See gh-28083
Imagine, you have a bean with an
init
method, annotated with@PostConstruct
and a configuration class, referencing the sameinit
method on its own.The
init
method will be invoked only once (what is pretty well).This is true for all method modifiers except
private
.As soon as you change the method modifier to
private
theinit
method is invoked twice.The text was updated successfully, but these errors were encountered: