Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use @PostConstruct?

In a managed bean, @PostConstruct is called after the regular Java object constructor.

Why would I use @PostConstruct to initialize by bean, instead of the regular constructor itself?

like image 904
Jan Avatar asked Aug 04 '10 14:08

Jan


People also ask

What is PostConstruct used for?

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection.

Why do we use PostConstruct in spring?

@PostConstruct and @PreDestroy and important annotations to use with the spring bean lifecycle management. We can use them to verify that bean is properly initialized and then close all the resources when the bean is removed from the spring context.

What is the purpose of PostConstruct PreDestroy annotation?

Same as with @PostConstruct, the methods annotated with @PreDestroy can have any access level, but can't be static. The purpose of this method should be to release resources or perform other cleanup tasks, such as closing a database connection, before the bean gets destroyed.

What can I use instead of PostConstruct?

We can replace @PostConstruct with BeanFactoryPostProcessor and PriorityOrdered interface. The first one defines an action that ought to be executed after the object's instantiation. The second interface tells the Spring the order of the component's initialization.


2 Answers

  • because when the constructor is called, the bean is not yet initialized - i.e. no dependencies are injected. In the @PostConstruct method the bean is fully initialized and you can use the dependencies.

  • because this is the contract that guarantees that this method will be invoked only once in the bean lifecycle. It may happen (though unlikely) that a bean is instantiated multiple times by the container in its internal working, but it guarantees that @PostConstruct will be invoked only once.

like image 91
Bozho Avatar answered Oct 22 '22 05:10

Bozho


The main problem is that:

in a constructor, the injection of the dependencies has not yet occurred*

*obviously excluding Constructor Injection


Real-world example:

public class Foo {      @Inject     Logger LOG;      @PostConstruct     public void fooInit(){         LOG.info("This will be printed; LOG has already been injected");     }      public Foo() {         LOG.info("This will NOT be printed, LOG is still null");         // NullPointerException will be thrown here     } } 

IMPORTANT: @PostConstruct and @PreDestroy have been completely removed in Java 11.

To keep using them, you'll need to add the javax.annotation-api JAR to your dependencies.

Maven

<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api --> <dependency>     <groupId>javax.annotation</groupId>     <artifactId>javax.annotation-api</artifactId>     <version>1.3.2</version> </dependency> 

Gradle

// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2' 
like image 24
Andrea Ligios Avatar answered Oct 22 '22 03:10

Andrea Ligios