Micronaut: I can't inject a bean with private constructor. Why?

Viewed 64

I injected a Bean via an Interface with field injection in a scheduled job. When the implementation of that interface has a private constructor.

@Singleton
public class MyJob {

    @Inject
    private MyInterface bean;

    @Scheduled(fixedDelay = "3s")
    public void iwas() {
        System.out.println(bean.getsomeString());
    }
}

The implementation of MyInterface (lets call it MyImpl) is annotaed with @Singleton. It has an empty default constructor. When I start the app, it prints the messages from MyImpl. But only if the constructor is not private. When its private, nothing happens. I dont even get a nullpointer exception.

I looked at the build-in beans - endpoint. In both cases the bean existed:

"org.example.$MyImpl$Definition": {
            "scope": "javax.inject.Singleton",
            "type": "org.example.MyImpl"
        }

What is happening? The debugger does not jump into the scheduled methode when the constructor of MyImpl is private

1 Answers

You can use @Creator see https://docs.micronaut.io/latest/guide/#introspection and scroll down to the "Static Creator Methods" section.

For example,

@Singleton
public class MyImpl implements MyInterface {

    private int count = 0;

    private MyImpl() {
        System.out.println("Private constructor for MyImpl");
    }

    @Override
    public String getsomeString() {
        return String.format("Getting String %d", ++count);
    }

    private static MyImpl instance = null;

    @Creator
    public static MyImpl getInstance() {
        if(instance == null) {
            instance = new MyImpl();
        }

        return instance;
    }

}
Related