cdiweld

Delegate bean resolution to another IoC container


Back in the middle age, my company created his own IoC container and since then our application is running with it. But the day has come for us to switch to CDI/Weld. Instead of switching the whole thing to CDI (we honeslty can't...), we would like to do this bits by bits starting with our front-end JSF.

The idea is to leave some of the bean resolution to Weld (e.g controller) and some to our old IoC container (e.g services)

For instance:

@Named
@RequestSCoped
ControllerA {

    @Inject
    private ServiceB service:
}

ControllerA should be managed by Weld, and ServiceB should remain in our old IoC container. Though, Weld should know to resolve it.

So far, our best clue is most probably to use cdi extensions and play with lifecycle events. Any example, feedback or advice is appreciated.


Solution

  • First, welcome to CDI! It's a great framework and a joy to use, especially in combination with JSF. I recommend reading Pro CDI in JavaEE8: https://link.springer.com/book/10.1007/978-1-4842-4363-3 for a deep dive into this which will help explain my answers below

    There's a couple of routes you should choose. The simplest would be to use a @Produces annotation in a class that delegates to the older IOC container. See here for an example: https://www.baeldung.com/java-ee-cdi

    The really slick, but slightly more complicated way, would be to create a CDI Portable Extension the can delegate resolution to your older container. This is very powerful and gives you hooks into several parts of the CDI container. For reference, see here: https://docs.jboss.org/weld/reference/latest/en-US/html/extend.html#extend

    In either scenario, you're going to have to understand the CDI lifecycle (everything is a proxy that delegates to a managed instance) thoroughly and how that interacts with your existing IOC container or you could face memory leaks.

    Good luck!