Is there any "PostConstruct" feature of lombok?

7.8k views Asked by At

Is there a way that I can define a "PostConstruct" initialization method with lombok?

@RequiredArgsConstructor(staticName = "of")
class MyObj {
    private final int x;
    private final int y;

    private int z;

    // not work
    @PostConstruct
    private void someInitLogic {
        z = x + y;
    }

    public void start() {
        // code use "z"
    }
}

So that I can init an object like:

MyObj obj = MyObj.of(1, 2);
obj.start();
1

There are 1 answers

0
Gautham M On

Since @PostConstruct is still an open issue and similar questions have popped up, I would like to suggest a workaround which could be followed if you have any of the below problems:

  1. You definitely not want to do all the this.x=x and replace all such constructors of the below form and with lombok.
    public SomeClass(A a, B b, C c,.............) {
        this.a = a;
        this.b = b;
        this.c = c;
        ........
        ........
        someInitLogic();
    }
    
  2. someInitLogic() is a new method and the class is part of an API or there are lots of places were the constructor is being invoked. So you do not want to force any code changes in the callers.

For anyone with the above issues, I suggest a workaround as follows:

  1. Add a dummy final variable to your class. Make it transient if class is Serializable.

    @Getter(value = AccessLevel.NONE)
    private final transient boolean dummy;
    
  2. Make the access level in @AllArgsConstructor or @RequiredArgsConstructor as private (even if you use a staticName), so that the constructor with the dummy parameter is not accessible outside.

    @RequiredArgsConstructor(staticName = "of",access = AccessLevel.PRIVATE)
    

    or

    @AllArgsConstructor(access = AccessLevel.PRIVATE)
    
  3. Write a constructor or static method which matches with the one that is currently being invoked as below:

    public MyClass(A a, B b, C c,.......) {
        this(a,b,c,......, false /* dummy*/);
        someInitLogic();
    }
    

    Or if you were using static method to invoke the constructor:

    public static MyClass of(A a, B b,......) {
        MyClass obj = MyClass.of(a,b,......, false /* dummy*/);
        obj.someInitLogic();
        return obj;
    }
    

This way you could reduce the boiler plate code, but at the same do not cause any code changes in the callers and could be easily refactored as soon as @PostConstruct is available.