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?
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?
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.
@PostConstruct
as well. –
Multiangular @PostConstruct
methods called on them yet so best to not use them... –
Orpine You always should prefer constructor injection, but having that said, if for any reason you have to use field injection, in that case the main problem is that:
in a constructor, the injection of the dependencies has not yet occurred
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](https://jaxenter.com/jdk-11-java-ee-modules-140674.html).
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'
in a constructor, the injection of the dependencies has not yet occurred.
true with setter or field injection, but not true with constructor injection. –
Alvertaalves @PostConstruct
in java 11
–
Shammer If your class performs all of its initialization in the constructor, then @PostConstruct
is indeed redundant.
However, if your class has its dependencies injected using setter methods, then the class's constructor cannot fully initialize the object, and sometimes some initialization needs to be performed after all the setter methods have been called, hence the use case of @PostConstruct
.
Also constructor based initialisation will not work as intended whenever some kind of proxying or remoting is involved.
The ct will get called whenever an EJB gets deserialized, and whenever a new proxy gets created for it...
There is only really one reason - because you want to take an action that requires the object to be fully constructed, like passing the "this" reference to an executor.
All the other reasons only occur if you fail to write code according to best practices (e.g. using field injections instead of constructor injection, etc).
But, since Java is free to re-order instructions in constructors, you cannot depend on any one field being fully constructed before handing off a reference to the object to an executor (i.e, the this reference should not escape until the constructor is finished)
© 2022 - 2024 — McMap. All rights reserved.
final
. Given that pattern, why is@PostConstruct
being added to J2EE - they must have seen another use case surely? – Altman@PostConstruct
is not used to inject your dependencies appropriately, to make sure they arefinal
, etc; it is used as an annotation for a utility that should be called exactly once even if the object is constructed multiple times by the IoC container. Not that I know how this would happen in the container, but it apparently can happen (see accepted answer). – Glary