seinecle
seinecle

Reputation: 10778

Except for managing user sessions, what are CDI for in Java SE /EE?

I understand the role of CDI in JavaEE web apps where they help pass on user session data between beans. Is there a good reason to use CDI in a Java SE or Java EE app, in the absence of user sessions?

Upvotes: 1

Views: 238

Answers (2)

Turing85
Turing85

Reputation: 20185

There seems to be a misunderstanding about what CDI is. I will explain what it is and then present some use cases and their benefits.


What is CDI?

CDI stands for "Contexts and Dependency Injection". It is the JEE-framwork for Dependency Injection. More information are available on the github tutorial of the project. I skip the explanation of dependency injection, the interested reader can look it up, e.g. on wikipedia.


What are the benefits of Dependency Injection?

The main benefit of deploying dependency injection is less friction: by injecting a dependency into a class, the class is decoupled from its dependency, and the dependency can be swapped without changing the code. I gave an in-depth example in this answer.

Dependency Injection can also lead to a cleaner architecture: a class defining REST-endpoints injects the necessary services. The services, in return, inject the necessary repositories/DAOs. A three-layered architecture is the most typical one, but not necessarily the only/right form. Keep in mind, however, that an architecture is

  • a) alive, i.e. it changes as the project evolves
  • b) something that should always be decided, or at lest discussed, with the project team. If the team is not fond of the architecture, it will not follow it and thus render it useless.
  • c) a subjective metric. Seldom will one find cases where one architecture is the best architeture. Most of the time, it is a matter of taste.

Examples of architectures/principles that are to a major part based on Dependency Injection are the SOLID-principles and hexagonal architecture.

Another benefit stemming from less coupling is better testability. By injecting mocks of the dependencies, one can test, for example, a single service in isolation.


Closing words

With great power comes great responsibility. Software engineering is not about decoupling everything from everything else. Most of the time, it is deciding where decoupling is needed and where coupling is wanted. Too much abstraction and decoupling can lead to an unreadable mess that is hard to maintain. As an example: As much as I like CDI events, they have the tendency to obscure the actual workflow of the business logic, especially if events are fired and observed at multiple places.

On a technical note, one should avoid field injection. The DI-framework must employ reflection in order to make field injection viable. This alone should be a deal breaker. Furthermore, the dependencies of a class get obscured. If a dependency is added or removed, the bean will still be created, possibly with a null value where another bean should be. The same holds true for setter injection. This is why constructor injection is considered the cleanest of the three methods.

Upvotes: 3

user1409784
user1409784

Reputation:

Here are some use cases for Java EE CDI in a JavaSE app

1 Event Bus

public void someMethod(@Observes @SomeFilter(SomeContext.SOME_FLAG) SomeEvent event) { ....

2 Patterns

@Produces
@Dependent
@ChartCanvasResult(DataFlow.CTS_FLOW)
Canvas canvasChart;

@Inject
@ModelResult(SomeContext.SOME_FLAG)
List<Double> someDataSinkList;

@Dependent
@Named("SomeService")
class SomeServiceImpl  implements SomeService {

3 Application bootstrap context

 Weld weld = new Weld();
 WeldSEShutdownHook shutdownHook = new WeldSEShutdownHook(weld);
 Runtime.getRuntime().addShutdownHook(shutdownHook);
 weldContainer = weld.initialize();

4 Runtime Context

   public Object call(Class<?> clazz) {
    log.debug("creating controller= {}", clazz.getSimpleName());

    try {
        return WeldSe.get(clazz);
    } catch (Exception e) {
        log.error("Error creating controller= " + clazz, e);
        throw new RuntimeException(e);
    }
}

1 to 4 above allow me to manage the bootstrap, runtime object graph, shutdown, and layout my code with enterprise patterns.
Weld

Upvotes: 0

Related Questions