Search code examples
javajakarta-eeejb

Assigning bean value in @PostConstruct


In the example below, I need to assign to Bean2 an attribute of Bean1. The attribute is null (see below). Also, "@PostConstruct Bean2" is printed before "After assignment".

Is there a way to make sure that Bean2 instance is created before assigning the value in Bean1?

@Stateless
public class Bean1 {

    @Inject
    private Bean2 bean2;

    String x;

    @PostConstruct
    private void init() {
         x = "Some Value";
         System.out.println("Before assignment");
         bean2.setX(x);
         System.out.println("After assignment");
    }
}

@Stateless
public class Bean2 {

    private String x;

    public setX(String x) {
         this.x = x;
    }

    @PostConstruct
    private void init() {
        System.out.println("@PostConstruct Bean2");
        System.out.println(x);  // <-- x is null
    }
  }

Solution

  • This is expected behavior based on how you've set things up. x should be properly set in Bean2 after the entire applicationContext has been spun up.

    To understand what's going on, notice that Bean2 is a dependency for Bean1. That means that Spring can't construct Bean1 until after Bean2 has been created. So it creates Bean2 first, and you see that x is null in the init() block because Bean1 hasn't been constructed yet to be able to set its value.

    Later, Bean1 will be constructed, its init() method will be called, and the value for x in Bean2 will be correctly set. But that happens long after Bean2's @PostConstruct has already finished.