The @PpstConstruct
annotation is part of JSR 330 (Dependency Injection) and states the associated method should be executed once and immediately after a bean's initialisation (see here for reference). In other words, the @PostConstruct
annotation is used to set up things after the constructor has been called (and internal variables have been initialised).
I used it to initialize more internal variables dependent on the local ones (e.g. create an object with initialised properties):
@Data
@ConfigurationProperties("com.mypackage")
class MyClass {
int myVariable;
String myVariableAsString;
public MyClass() {
// ...
}
@PostConstruct
private finishInitialisation() {
this.myVariableAsString = String.valueOf(myVariable);
}
}
In one of the applications, I wanted to see the variables for my app as found from a configuration server, via the following code:
@EventListener
public void handleContextRefresh(ContextRefreshedEvent event) {
final Environment env = event.getApplicationContext()
.getEnvironment();
LOGGER.info("Active profiles: {}", Arrays.toString(env.getActiveProfiles()));
final MutablePropertySources sources = ((AbstractEnvironment) env).getPropertySources();
StreamSupport.stream(sources.spliterator(), false)
.filter(ps -> ps instanceof EnumerablePropertySource)
.map(ps -> ((EnumerablePropertySource) ps).getPropertyNames())
.flatMap(Arrays::stream)
.distinct()
.filter(prop -> !(prop.contains("credentials") || prop.contains("password")))
.forEach(prop -> LOGGER.info("{}: {}", prop, env.getProperty(prop)));
}
Unfortunately, it became evident that some variables were initialised with null
, which messed up my getter of the coposite variable. Ouch!
As a result, when I wanted to initialise complex objects, I had to shift from @PostConstruct
to use @Bean
annotation in combination eventually with @Singleton
.
HTH,
Member discussion: