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:
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;
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.
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.