JEE and dynamic Dependency Injection

During the last weeks a colleague of mine came to my desk and ask for a solution in JEE6 for the following

Problem

The implementation that should be used for injection via @Inject must be determined during runtime by call parameters of the target bean.

JEE didn’t have, or to be precise I didn’t know a solution for that, a direct solution for that kind of problem.

So my colleague tried this

First solution

He create the required object by his own via new and used setters to manually inject the dependencies, like database connection, … .
However, he quickly realized, that this approach is only sufficient if you have very similar variants of objects (meaning, same dependencies and so on). So if you have an new implementation, which requires a totally different set of dependencies the trouble began.

Another problem with this approach is, that you create / destroy the objects at the JEE container past. So the container isn’t aware of it and you can’t additionally use the lifecycle methods like PostConstruct or PreDestroy.

A possible

Solution

is to use the class Instance with the qualifier @Any. Instance provides a generic container for any implementation of an interface which matches the interfaces and the provided qualifier (here @Any). Additionally this class provides for every available instance the methods isAmbiguous and isUnsatisfied to check if the dependencies are satisfied.

This object can now used to create a factory method which returns the requested object. The cool fact is, that this object is completely JEE aware.
Last but not least a simple

Example

This example is around a simple tax calculator.
This calculator calculates the tax based upon a previous selection of the user. The available variants are “no taxes”, “fixed”, “progressive” and “unbelievable”).

I will demonstrate here only the main components. The complete project is available on GitHub.

The core component is this factory:

As you see here all implemented TaxCalculations are injected via the Instance object. The requested TaxCalculation is determined in the method getTaxCalculationForName via an AnnotationLiteral (see next code example).

The AnnotationLiteral is required to use the select method of Instance. This method returns all instances of the available implementations which matches the conditions:

The qualifier can be realized like this

I hope this little example shows how JEE can be used to easy realize such a mechanism. This approach has also the benefit, that you can easily add new implementations of the TaxCalculation without changing the implementation.

Conclusion

The problem of my colleague had thus be solved in a very elegant matter.
In opposite to my approach, my colleague uses information from the database to determine the dynamic dependency.

I hope that I had shown you that JEE can also be easily used in a dynamic environment. Only a little bit knowledge and “creativity” is required.

 
15 Kudos
Don't
move!

Leave a Reply

Your email address will not be published. Required fields are marked *