@PostConstruct not so Good Best Practice
1 min read

@PostConstruct not so Good Best Practice

Don;t use @PostConstruct with debug code and a ConfigurationServer.
@PostConstruct not so Good Best Practice

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,