Master Spring Boot 3 Bean Lifecycle: @PostConstruct & @PreDestroy Alternatives

This article explains the purpose and usage of Spring Boot’s @PostConstruct and @PreDestroy annotations for bean initialization and cleanup, discusses their migration to Jakarta EE in Spring Boot 3+, and presents modern alternatives such as @EventListener with ApplicationReadyEvent, DisposableBean, and destroyMethod configurations, complete with code examples.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Master Spring Boot 3 Bean Lifecycle: @PostConstruct & @PreDestroy Alternatives

1. Introduction

In Spring Boot development, @PostConstruct and @PreDestroy are important lifecycle annotations for managing bean initialization and cleanup.

@PostConstruct

Marks a method to be executed immediately after bean dependencies are injected. Commonly used for initialization tasks such as loading configuration or opening resources.

Usage: The method runs after the bean is created and dependencies are injected.

@PreDestroy

Marks a method to be executed before the bean is destroyed, typically during application shutdown, to release resources.

Usage: Ensures resources like database connections are closed to avoid leaks.

2. Practical Examples

2.1 Using @PostConstruct to preload data

@Service
public class UserService {
    private final UserRepository userRepository;
    private Map<Long, User> userCache = new HashMap<>();

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @PostConstruct
    public void init() {
        userRepository.findAll().forEach(user -> userCache.put(user.getId(), user));
    }

    public User getUserById(Long id) {
        return userCache.get(id);
    }
}

When the application starts, Spring creates the UserService bean, injects UserRepository, then runs the init() method to fill the cache.

Spring creates UserService bean.

Container injects UserRepository.

@PostConstruct
init()

loads user data into the cache.

2.2 Replacing @PostConstruct with @EventListener(ApplicationReadyEvent)

@EventListener(ApplicationReadyEvent.class)

runs after the entire Spring context is fully initialized, ensuring that initialization logic executes only when the application is ready.

@Component
public class PackStartupTask {
    @EventListener(ApplicationReadyEvent.class)
    public void onApplicationReady() {
        performStartupTasks();
    }

    private void performStartupTasks() {
        // ...
    }
}

2.3 Using @PreDestroy for cleanup

@Service
public class FileService {
    private BufferedReader bufferedReader;

    public FileService() {
        try {
            this.bufferedReader = new BufferedReader(new FileReader("example.txt"));
            System.out.println("File opened successfully.");
        } catch (IOException e) {
            System.err.println("Failed to open file: " + e.getMessage());
        }
    }

    @PreDestroy
    public void cleanupFileResource() {
        try {
            if (bufferedReader != null) {
                bufferedReader.close();
                System.out.println("File resource cleaned up successfully.");
            }
        } catch (IOException e) {
            System.err.println("Failed to clean up file resource: " + e.getMessage());
        }
    }
}

2.4 Alternative cleanup approaches

Instead of @PreDestroy, you can implement DisposableBean or define a bean with a destroyMethod .

@Component
public class MyResource implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("Performing cleanup for MyResource...");
        // cleanup logic
    }
}
@Configuration
public class AppConfig {
    @Bean(destroyMethod = "customCleanup")
    public MyResource myResource() {
        MyResource resource = new MyResource();
        System.out.println("MyResource bean created.");
        return resource;
    }

    public static class MyResource {
        public void customCleanup() {
            System.out.println("Custom cleanup for MyResource...");
            // cleanup logic
        }
    }
}

Note: Starting with Java 9+, @PostConstruct and @PreDestroy were moved from javax.annotation to jakarta.annotation, but they remain usable in Spring Boot 3+.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring BootBean LifecycleEventListenerPostConstructPreDestroy
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.