{"id":230,"date":"2024-06-28T20:00:00","date_gmt":"2024-06-28T23:00:00","guid":{"rendered":"https:\/\/springmasteryhub.com\/?p=230"},"modified":"2024-06-28T20:00:00","modified_gmt":"2024-06-28T23:00:00","slug":"predestroy-and-postconstruct-in-spring-managing-bean-lifecycle","status":"publish","type":"post","link":"https:\/\/springmasteryhub.com\/?p=230","title":{"rendered":"@PreDestroy and @PostConstruct in Spring: Managing Bean Lifecycle"},"content":{"rendered":"\n<p>These annotations are called at specific moments in the bean lifecycle.<\/p>\n\n\n\n<p>They allow you to define methods executed after a bean is created and before the beans are destroyed.<\/p>\n\n\n\n<p>Both annotations come from Jakarta EE and can be used in Spring projects.<\/p>\n\n\n\n<p>They are useful for managing resources that are only used in the bean\u2019s life cycle scope.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Let\u2019s see a practical example:<\/h3>\n\n\n\n<p>We have a <code>CustomNotificationService<\/code> bean that uses an <code>ExternalMessageSender<\/code><\/p>\n\n\n\n<p>Before sending messages, you need to create a connection to an external API and authenticate.<\/p>\n\n\n\n<p>So our <code>ExternalMessageSender<\/code> should look like this:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class ExternalMessageSender {\n\n    public void authenticate(String apiKey, String secret) {\n        log.info(&quot;Called on bean creation&quot;);\n    }\n\n    public void sendMessage(String recipient, String content) {\n        log.info(&quot;Message sent to &quot; + recipient + &quot;: &quot; + content + &quot; when processing the request&quot;);\n    }\n\n    public void closeConnection() {\n        log.info(&quot;Called on bean destruction&quot;);\n    }\n}\n\n<\/pre><\/div>\n\n\n<p>Now, let&#8217;s create the <code>CustomNotificationService<\/code> bean, where the fun happens.<\/p>\n\n\n\n<p>This bean will be request-scoped, so it becomes easier to see the bean lifecycle.<\/p>\n\n\n\n<p>The scope will be <code>requested<\/code> so the bean will be available only in the It will be created when a request is made, and destroyed after the request is done.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Service\n@Scope(value = &quot;request&quot;, proxyMode = ScopedProxyMode.TARGET_CLASS)\npublic class CustomNotificationService {\n\n    private ExternalMessageSender messageSender;\n\n    @PostConstruct\n    public void initialize() {\n        messageSender = new ExternalMessageSender(&quot;&lt;https:\/\/api.example.com\/messages&gt;&quot;);\n        messageSender.authenticate(&quot;api_key&quot;, &quot;secret&quot;);\n    }\n\n    public void sendNotification(String userId, String message) {\n        messageSender.sendMessage(userId, message);\n    }\n\n    @PreDestroy\n    public void cleanup() {\n        messageSender.closeConnection();\n    }\n}\n\n\n<\/pre><\/div>\n\n\n<p>So we used the <code>initialize()<\/code> method as <code>@PostConstruct<\/code> after the bean was created.<\/p>\n\n\n\n<p>We used the <code>cleanup()<\/code> method will be used before the bean was destroyed.<\/p>\n\n\n\n<p>And we can use the resource we created in Bean in all the other methods.<\/p>\n\n\n\n<p>To exercise this code, we can create this controller:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\/\/ NotificationController class\n@RestController\npublic class NotificationController {\n    \/\/ ... (Autowired notificationService) ...\n\n    @PostMapping(&quot;\/send-notification&quot;)\n    public String sendNotification(@RequestBody NotificationRequest request) {\n        String userId = request.userId();\n        String message = request.message();\n        notificationService.sendNotification(userId, message);\n        return &quot;Notification sent successfully!&quot;;\n    }\n}\n\n\/\/ NotificationRequest record\npublic record NotificationRequest(\n        String userId,\n        String message\n) {}\n\n\n<\/pre><\/div>\n\n\n<p>Calling the endpoint <code>\/send-notification<\/code>, you&#8217;ll see the following output in logs, demonstrating the methods being executed at each stage of the bean&#8217;s lifecycle:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: bash; title: ; notranslate\" title=\"\">\n2024-06-27T21:30:48.287-03:00 INFO 14944 --- &#x5B;nio-8080-exec-3] c.s.m.postandpre.ExternalMessageSender   : Called on bean creation\n2024-06-27T21:30:48.287-03:00 INFO 14944 --- &#x5B;nio-8080-exec-3] c.s.m.postandpre.ExternalMessageSender   : Message sent to 123: Hello world @PostConstruct and @PreDestroy. when processing the request\n2024-06-27T21:30:48.289-03:00 INFO 14944 --- &#x5B;nio-8080-exec-3] c.s.m.postandpre.ExternalMessageSender   : Called on bean destruction\n\n\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Conclusion<\/h3>\n\n\n\n<p>In this blog post, you learned how to leverage the @PostConstruct and @PreDestroy annotations to add custom behavior during the lifecycle of your Spring beans.<\/p>\n\n\n\n<p>If you found this topic interesting, follow me for more insights into Spring annotations and other valuable tips!<\/p>\n\n\n\n<p><a href=\"https:\/\/twitter.com\/WillianFMoya\">Willian Moya (@WillianFMoya) \/ X (twitter.com)<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/www.linkedin.com\/in\/willianmoya\/\">Willian Ferreira Moya | LinkedIn<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>These annotations are called at specific moments in the bean lifecycle. They allow you to define methods executed after a bean is created and before the beans are destroyed. Both annotations come from Jakarta EE and can be used in Spring projects. They are useful for managing resources that are only used in the bean\u2019s [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6],"tags":[13,18,20,22,23],"class_list":["post-230","post","type-post","status-publish","format-standard","hentry","category-spring","tag-java","tag-programming","tag-software-development","tag-spring-boot","tag-spring-framework"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/posts\/230","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=230"}],"version-history":[{"count":0,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=\/wp\/v2\/posts\/230\/revisions"}],"wp:attachment":[{"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=230"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=230"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springmasteryhub.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=230"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}