Search code examples
jakarta-eedependency-injectioncdi

Is application server able to optimize scopes of CDI instances or should we define CDI scopes ourselves


recently we had a discussion regarding the use of the CDI API inside a microservice compliant project.

There was a debate regarding the way we should use the CDI and there were two different opinions:

  1. Do not use any of the annotations provided by the CDI, and let the container decide the scope of the instances:
public class MyService {

    @Inject
    private MyLogger logger;

    @Inject
    private MyDAO myDAO;

    @Inject @ElementsById
    private MyModel myModel;

And the service is used inside a RestContoller:

public class MyREST implements MyApi {
    @Inject
    private MyService myService;
  1. Use annotations like @AppplicationScoped for the Rest and the Service layer and do not let the container / application server decide the scope of the beans.

What would be the best way to move forward with this? Is the application server (Wildfly) able to optimize the scopes of the instances or should we take control over the CDI and define the scopes ourselves.


Solution

  • A few things to bear in mind here.

    Firstly about container and bean scopes:

    let the container decide the scope of the instances

    The CDI container cannot really decide a scope - if the scope is undefined, then it will always use @Dependent which may not be what you want because that scope always creates a new instance for each injection point.

    Is the application server (Wildfly) able to optimize the scopes of the instances or should we take control over the CDI and define the scopes ourselves.

    With what I said above, it should be already clear that neither WildFly nor any other server can actually optimize scopes for you - it is defined in the specification that when there is no scope defined (and the class is to be turned into a CDI bean) it will use @Dependent.

    Secondly, bean discovery modes:

    Whether CDI container discovers a bean or not depends on a bean discovery mode. This is detailed in the following specification section - in short the modes are either all or annotated (well, none too) and depend on whether you have beans.xml and what's in it and whether you have bean defining annotations on your to-become-beans-classes.

    Last but not least, what is a good practice:

    I'd suggest to use an implicit bean archive approach - for this you don't even need to have beans.xml present but all your beans need to have at least some bean defining annotation. This way you minimize the time it takes CDI container to perform discovery and initialization as it only works with beans you really need/want as opposed to having mode all which tries to turn all classes into beans when eligible.