It is quite confusing when the Java inheritance is mingled with the PostConstruct annotation. Based on my tests, I found the following.
Suppose there are two classes.
class A {
@PostConStruct
private void init(){
}
}
class B extends A {
}
Case 1
For the above case, the execution order is
- Constructor of A
- Constructor of B
- init method of A.
So the annotation @PostConstruct is inherited even when the annotated method is private in the parent class.
Case 2
Now if the class B has its own @PostConstruct method such as the following:
@PostConstruct
private void my_init(){
}
Then the init() method of A will not be called. Instead, my_init() is called. So it seems that in the class hierarchy, only one PostConstruct annotated method is called.
Case 3
Now if the class B does not have its own @PostConstruct. But it overrides the @PostConstruct annotated method in its parent class.
class A {
@PostConStruct
public void init(){
System.out.println("A init()");
}
}
class B extends A {
@Override
public void init(){
System.out.println("B init()");
}
}
In this case the @PostConstruct method init() is called. But the init() method used is from class B. So it will print "B init()". Note that if the init() method in class A is private, then "A init()" will be printed out. In this case, the init() method of B is not an override method. Actually you have to remove its @Override annotation. Otherwise it won't compile.
Conclusion
In summary, if there is a method with the annotation @PostConstruct in a class C or its parent classes, then the annotated method will be called after the constructor of C is called. In case that @PostConstruct appears in multiple classes in the class hierarchy, the one closest to the class C will be called. Furthermore, if that annotated method is overridden by its subclasses, then the overriding method will be called. Of course, I think it is bad to declare the @PostConstruct annotated method as public or protected. It should be private so it won't be overridden.
case 2 is wrong. In fact, the super class postconstruct will be invoked before the child class's postconstruct. But make no mistake, both of them are going to be run.
ReplyDelete