Spring Bean生命周期(初始化与销毁)自定义方法执行异常求助
Hey there! It’s super confusing when Spring’s bean lifecycle behaves opposite to what the tutorials teach—let’s break down the most likely reasons why your CurrentAccount bean’s destroy method is firing before initialization, and how to fix it.
Common Causes & Fixes
1. Mixed Up Configuration Parameters
Double-check how you’ve configured your bean’s lifecycle methods—this is the most frequent culprit. It’s easy to swap initMethod and destroyMethod by accident in your @Bean definition or XML config:
Example of the mistake:
@Bean(initMethod = "cleanup", destroyMethod = "initialize") // Oops! Swapped methods public CurrentAccount currentAccount() { return new CurrentAccount(); }
Or in XML:
<bean id="currentAccount" class="com.yourpackage.CurrentAccount" init-method="cleanup" destroy-method="initialize"/> <!-- Wrong order -->
Fix: Verify that initMethod points to your actual initialization logic, and destroyMethod maps to your cleanup code.
2. Misimplemented Lifecycle Interfaces
If CurrentAccount implements InitializingBean or DisposableBean, make sure you didn’t mix up the method overrides:
Incorrect implementation:
public class CurrentAccount implements Account, InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { // Accidentally put destroy logic here System.out.println("Destroying CurrentAccount..."); } @Override public void destroy() throws Exception { // Accidentally put initialization logic here System.out.println("Initializing CurrentAccount..."); } }
Fix: Ensure afterPropertiesSet() contains your setup code, and destroy() handles cleanup.
3. Initialization Failure Triggering Cleanup
If your bean’s initialization method throws an uncaught exception, Spring will immediately call the destroy method to clean up the partially created bean. This can make it look like destroy runs before initialization, but actually the initialization failed mid-execution.
Example scenario:
public class CurrentAccount implements Account { @PostConstruct public void init() { throw new RuntimeException("Critical error during initialization!"); } @PreDestroy public void destroy() { System.out.println("Running destroy method..."); } }
Fix: Add error handling to your initialization logic, or debug the exception to resolve the root cause of the failure.
4. Accidental Manual Trigger of Destroy
If you’re manually managing bean lifecycle (e.g., calling applicationContext.destroyBean() somewhere in your code), double-check that you aren’t invoking the destroy method before the bean is fully initialized. This is especially common in test code or quick prototype projects.
5. Annotation Mix-Up
If you’re using @PostConstruct and @PreDestroy annotations, confirm they’re attached to the correct methods. It’s easy to paste the wrong annotation when copying code:
Wrong annotation placement:
public class CurrentAccount implements Account { @PreDestroy // Should be @PostConstruct public void setup() { // Initialization logic } @PostConstruct // Should be @PreDestroy public void teardown() { // Cleanup logic } }
Fix: Swap the annotations to match the method’s purpose.
Quick Debugging Steps
- Add clear log statements to each lifecycle method with timestamps, so you can track exactly when each runs.
- Inspect your Spring container’s lifecycle: Ensure the
ApplicationContextisn’t being closed immediately after creation (e.g., in a main method wherecontext.close()is called right aftercontext.refresh()). - Check for any custom
BeanPostProcessorimplementations that might be interfering with the lifecycle order.
内容的提问来源于stack exchange,提问作者Kramer

