CDI: Dynamical injection of a group of classes how to? - java

I need to dynamically Inject a variable group of classes in my application. The purpose is, as the application grows, only have to add more classes inheriting the same interface. This is easy to do with tradicional java as I just need to search for all classes in a package and perform a loop to instantiate them. I want to do it in CDI. For example:
public MyValidatorInterface {
public boolean validate();
}
#Named
MyValidator1 implements MyValidatorInterface
...
#Named
MyValidator2 implements MyValidatorInterface
...
Now the ugly non real java code just to get the idea of what I want to do:
public MyValidatorFactory {
for (String className: classNames) {
#Inject
MyValidatorInterface<className> myValidatorInstance;
myValidatorInstance.validate();
}
}
I want to loop over all implementations found in classNames list (all will be in the same package BTW) and Inject them dynamically so if next week I add a new validator, MyValidator3, I just have to code the new class and add it to the project. The loop in MyValidatorFactory will find it, inject it and execute the validate() method on the new class too.
I have read about dynamic injection but I can't find a way to loop over a group of class names and inject them just like I used to Instantiate them the old way.
Thanks

What you are describing is what Instance<T> does.
For your sample above, you would do:
`#Inject Instance<MyValidatorInterface> allInstances`
Now, allInstances variable contains all your beans which have the given Type (MyValidatorInterface). You can further narrow down the set by calling select(..) based on qualifiers and/or class of bean. This will again return an Instance but with only a subset of previously fitting beans. Finally, you call get() which retrieves the bean instance for you.
NOTE: if you call get() straight away (without select) in the above case, you will get an exception because you have two beans of given type and CDI cannot determine which one should be used. This is implied by rules of type-safe resolution.
What you most likely want to know is that Instance<T> also implements Iterable so that's how you get to iterate over the beans. You will want to do something like this:
#Inject
Instance<MyValidatorInterface> allInstances;
public void validateAll() {
Iterator<MyValidatorInterface> iterator = allInstances.iterator();
while (iterator.hasNext()) {
iterator.next().callYourValidationMethod();
}}
}

Related

How to inject a variable number of similar components that have dependencies themselves?

Background
I want to realize dependency injection in Python using injector (or pinject) which itself heavily borrows from guice. While an answer using Python/injector would be ideal, I'm also very happy about solutions/approaches that feature Java/guice.
Intention
I'll give you a quick summary of what I want to achieve: I have a component that depends on a list/sequence of other components that all implement the same interface. Those components have dependencies themselves which may vary amongst the different implementations. The concrete types (implementations) shall be configurable by the user (or using any mechanism of the DI framework).
Example
Yes, I've read Modules should be fast and side-effect free which suggests not to use an XML file for configuration, however as I don't know how to realize this within the framework I'll use one to demonstrate the dependency structure:
<RentingAgency>
<Vehicles>
<Car>
<DieselEngine></DieselEngine>
</Car>
<Car>
<PetrolEngine></PetrolEngine>
</Car>
<Bike></Bike>
</Vehicles>
</RentingAgency>
In this example there is a renting agency (the component that depends on a list of others) that rents out all kinds of vehicles (the interface). The specific vehicles in their fleet (in this case two cars and one bike) should be configurable but fixed during runtime. The vehicles themselves can have dependencies and they can be different depending on the type of vehicle (a car depends on a motor, a bike has no dependencies in this case).
Question
How can I construct the renting agency within the DI framework so that all required vehicles are injected and their dependencies resolved properly?
Maybe helpful
Multibinder
I've read about Multibinder (injector seems to have something similar with Binder.multibind) which allows for injecting a collection of objects that implement the same interface. However:
Can it be used to create multiple instances of the same class that need to receive different dependencies (the two cars (Class Car) in the example have different motors: Interface Motor, Class DieselEngine, class PetrolEngine)?
Using providers to accomplish that task seems to me like giving up the benefits of dependency injection: I could manually create the Car instances in the provider, passing the required Motor as argument, however because this pattern repeats further down the chain (i.e. multiple Motors of the same type are used and they also have dependencies) I want to use dependency injection for generating those objects too. But to manually use them in the provider it seems to me like I have to obtain the instances directly from the injector. The docs mention that injecting the injector is a rare case and from my understanding of dependency injection, the great benefit is that one can request a component and all dependencies are resolved by the framework automatically.
Also because I actually use Python I'm not sure if this approach is appropriate (as Python is quite flexible when it comes to dynamic code generation). Also injector.Injector.get.__doc__ mentions
Although this method is part of :class:Injector's public interface
it's meant to be used in limited set of circumstances.
For example, to create some kind of root object (application object)
of your application (note that only one get call is needed,
inside the Application class and any of its dependencies
:func:inject can and should be used):
Dependency injection frameworks are primarily for dependencies and because your Vehicles object is configured by the user at runtime it is more like application data than a dependency. It probably can't just be injected in one shot using MultiBinding unless you know it at compile time.
Likewise, you are right in saying that it would not be a good approach to construct your set of components by iterating and calling injector.getInstance(Bike.class) etc. For one, this is not good for testing.
However, because the objects contained in Vehicles have their own dependencies you can leverage the DI framework in the creation of your Vehicles object. Remember, also, that although you cannot bind a Provider to an implementation, when you bind a key Guice will inject that provider for you.
For the simple example in the post, consider creating a VehicleFactory. Inside, you could have something like the following:
public class VehicleModule implements Module {
#Override
public void configure(Binder binder) {
binder.bind(DieselEngine.class).toProvider(DieselEngineProvider.class);
binder.bind(PetrolEngine.class).toProvider(PetrolEngineProvider.class);
binder.bind(Bike.class).toProvider(BikeProvider.class);
}
}
public class DieselEngineProvider implements Provider<DieselEngine> {
#Inject
public DieselEngineProvider() {
//if DieselEngine has any dependencies, they can be injected in the constructor
//stored in a field in the class and used in the below get() method
}
#Override
public DieselEngine get() {
return new DieselEngine();
}
}
public class VehicleFactory {
private final CarFactory carFactory;
private final Provider<Bike> bikeProvider;
#Inject
public VehicleFactory(CarFactory carFactory, Provider<Bike> bikeProvider) {
this.carFactory = carFactory;
this.bikeProvider = bikeProvider;
}
public Bike createBike() {
return bikeProvider.get();
}
public Car createDieselCar() {
return carFactory.createDieselCar();
}
public Car createPetrolCar() {
return carFactory.createPetrolCar();
}
}
public class CarFactory {
private final Provider<DieselEngine> dieselEngineProvider;
private final Provider<PetrolEngine> petrolEngineProvider;
#Inject
public CarFactory(Provider<DieselEngine> dieselEngineProvider, Provider<PetrolEngine> petrolEngineProvider) {
this.dieselEngineProvider = dieselEngineProvider;
this.petrolEngineProvider = petrolEngineProvider;
}
public Car createDieselCar() {
return new Car(dieselEngineProvider.get());
}
public Car createPetrolCar() {
return new Car(petrolEngineProvider.get());
}
}
As you mention, there is the danger of this becoming 'factories all the way down', but Guice can help you here.
If the production of Engine becomes more complicated and involves a combination of different parameters, you can use tools like AssistedInject to auto-create the factories for you.
If you end up with a set of common dependencies and uncommon dependencies that you want to use to create different 'flavours' of an object then you have what is known as the robot legs problem then Guice can solve it using private modules.
Do note the following caveat from the Dagger 2 user guide:
Note: Injecting Provider has the possibility of creating confusing
code, and may be a design smell of mis-scoped or mis-structured
objects in your graph. Often you will want to use a factory or a
Lazy or re-organize the lifetimes and structure of your code to be
able to just inject a T.
If you follow this advice, it would seem that you would have to carefully balance using providers and using factories to create your Vehicle.

Interface to concrete class conditional instantiation in Spring

I have a Spring based Java application where a lot of classes use the following autowired interface.. they work off this interface at all places.
#Autowired
private IOperatingSystemManager m_operatingSystemManager;
Right now, there is only one implementation of the interface as follows:
#Component
public class WindowsManager implements IOperatingSystemManager
{
// Windows based shenanigans
}
And the application works as expected. Spring is happy. Everybody is happy.
Alright, not everybody...
So, I want to add another concrete implementation of IOperatingSystemManager ..
#Component
public class LinuxManager implements IOperatingSystemManager
{
// Linux based shenanigans
}
What we want is the auto wiring of IOperatingSystemManager conditionally based on a properties file setting. (say.. os=windows.. basically something that is an arbitrary string and cannot be derived from system properties etc. simply because this is a dummy example. the actual managers are not OS related.)
I don't want to change any of the classes who have autowired to the interface and are working off the interface. All I need is for Spring to look at some logic that will dictate the Autowiring of the variables and wire up the right concrete instance for:
#Autowired
IOperatingSystemManager m_operatingSystemManager
at all the gazillion places.
The documentation & web search talk about profiles, condition, bean factory, qualifiers etc.. but we don't want to use Profiles; and Qualifiers seem to be needing changes to all the interface variable annotations.
Factory methods look promising, but being new to Spring, couldn't find a crisp answer.
What is a simple and recommended way to achieve this?
Instead of scanning the WindowsManager class, create one concrete instance that implements the IOperatingSystemManager interface or another one, depending on the your logical conditions.
First, remove the #Component annotation from the WindowsManager class.
Then, create and scan this #Configuration class, which will act as a factory for your beans:
#Configuration
public class OperatingSystemManagerFactory {
#Bean
public IOperatingSystemManager getOperatingSystemManager() {
if ( /* some logic that evaluates to true if windows */ ) {
return new WindowsManager();
} else {
// Linux default option ;)
return new LinuxManager();
}
}
}
With this solution, you shouldn't need to update anyone of your classes that reference the IOperatingSystemManager interface.
I dont know which version of spring you are using but you have options for this
http://www.intertech.com/Blog/spring-4-conditional-bean-configuration/
Here, as you can see, you can create a bean based on a condition that you can decide. It actully gave your example, Windows and Linux :), so i believe thats what you are looking for.
Edit:
If you are using spring-boot, you have some other Conditional annotations
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html#boot-features-condition-annotations

How to deal with special "constant" instances of object when using DI

My project is heavily using dependency injection, and I'm being very careful to avoid service locator antipattern. All objects are structured using constructor injection that allow easily identifiable list of dependencies. Now I'm building an object, and it has a special "constant" instance, which is basically static/singleton (consider example of something like Integer.MinValue). So my initial reflex was to create a static field with a static "getter" method, which would create the instance of the object if it wasn't previously created. The object itself has dependencies however, so I'm confused on what's the best practice for instantiating this "special instance". I'm looking for recommendations on how to best structure code in this scenario, ideally without having to call upon the container for resolution of dependencies. Some code:
public class PressureUnit extends DataUnit {
private static PressureUnit standardAtmosphere;
public static PressureUnit StandardAtmosphere() {
if(standardAtmosphere == null){
standardAtmosphere = new PressureUnit(1013.25); // this line is what is bothering me as I need to resolve other dependencies (have to use new as it's a static method and can't be injected like everywhere else)
}
return standardAtmosphere;
}
#AssistedInject
public PressureUnit(ITimeProvider timeProvider, IUnitProvider unitProvider, #Assisted double value) {
this(timeProvider, unitProvider, value, PressureUnits.hPa);
}
...
}
I really don't see any problem in your code since you are not newing up dependencies here and there, now with that being said i can give some suggestions:
If you specifically want the container to call an existing static factory method, you can use StaticFactoryExtension.
Why don't you use a factory.
Consider refactoring you design and removing the static method if possible.

Configuration class - best practice with Guice

Background: I'm using Google Guice and so it's easier to pass through the configuration class but I think this is not the best way.
I have a configuration class which stores some paths:
class Configuration{
String getHomePath();
String getUserPath();
}
Also I have a class "a" which needs the "homepath" and a class "b" which needs the "userpath".
Is it better to pass the configuration class through the constructor of class a and b or only pass through the specific path?
If you're really using Guice correctly all your configuration like this should appear in modules' configure method. So:
Remove the configuration class.
Create annotation classes, probably called HomePath and UserPath.
Where class a uses getHomePath() replace that with a String field member named homePath.
Where class b uses getUserPath() replace that with a String field member named userPath.
Modify the class a and b constructors to be #Inject annotated (should already be) and take in a String parameter, respectively annotated with #HomePath and #UserPath and assign the String field member that injected value.
Create bindings in your module's configure method use .annotatedWith() which define correct values; if they're only available at run time, bind a provider.
E.G.
class a {
private String homePath;
#Inject
public a(#HomePath String homePath) {
this.homePath = homePath;
}
public String tellMeAboutHome() {
return "We live in a nice home called " + homePath;
}
}
class customModule extends AbstractModule {
public static final String userPath = "/home/rafael";
public void configure() {
bind(String.class).annotatedWith(HomePath.class).to("/home/");
bind(String.class).annotatedWith(UserPath.class).to(userPath);
}
}
If creating annotations is too much work for you, use the #Named annotation Guice ships with.
There's no single answer to your question, there are only options to choose from, based on your specific situation.
If you know your Configuration class is going to grow AND if it's likely for your A and B classes will use more from it, then pass the whole Configuration object to their constructors. NB: I know this is against the YAGNI principle but sometimes you may know you're gonna need it ;-)
Otherwise, you can consider using #Named injection of your paths so that you reduce A and B classes dependencies to their minimum, which is a good design practice.
The general rule is code to make the dependency graph (which classes know about or depend on other classes/ interfaces) as simple, regular and fixed as possible.
If not passing the Configuration class makes a or b have zero dependencies on on user-written classes, or is necessary to avoid a dependency loop, then use the individual path strings. Otherwise, if it makes more sense to say 'this class has access to configuration info, in a way that may change in the future', pass the class.
I'd avoid the singleton approach, especially if you already have Guice set up.

Java - Register all classes annotated with #MyAnnotation

I have an annotation #MyAnnotation and I can annotate any type (class) with it. Then I have a class called AnnotatedClassRegister and I would like it to register all classes annotated with #MyAnnotation so I can access them later. And I'd like to register these classes automatically upon creation of the AnnotatedClassRegister if possible, and most importantly before the annotated classes are instantiated.
I have AspectJ and Guice at my disposal. The only solution I came up with so far is to use Guice to inject a singleton instance of the AnnotatedClassRegister to an aspect, which searches for all classes annotated with #MyAnnotation and it adds the code needed to register such class in its constructor. The downside of this solution is that I need to instantiate every annotated class in order for the code added by AOP to be actually run, therefore I cannot utilize lazy instantiation of these classes.
Simplified pseudo-code example of my solution:
// This is the class where annotated types are registered
public class AnnotatedClassRegister {
public void registerClass(Class<?> clz) {
...
}
}
// This is the aspect which adds registration code to constructors of annotated
// classes
public aspect AutomaticRegistrationAspect {
#Inject
AnnotatedClassRegister register;
pointcutWhichPicksConstructorsOfAnnotatedClasses(Object annotatedType) :
execution(/* Pointcut definition */) && args(this)
after(Object annotatedType) :
pointcutWhichPicksConstructorsOfAnnotatedClasses(annotatedType) {
// registering the class of object whose constructor was picked
// by the pointcut
register.registerClass(annotatedType.getClass())
}
}
What approach should I use to address this problem? Is there any simple way to get all such annotated classes in classpath via reflection so I wouldn't need to use AOP at all? Or any other solution?
Any ideas are much appreciated, thanks!
It's possible:
Get all paths in a classpath. Parse System.getProperties().getProperty("java.class.path", null) to get all paths.
Use ClassLoader.getResources(path) to get all resources and check for classes: http://snippets.dzone.com/posts/show/4831
It isn't simple that much is sure, but I'd do it in a Pure Java way:
Get your application's Jar location from the classpath
Create a JarFile object with this location, iterate over the entries
for every entry that ends with .class do a Class.forName() to get the Class object
read the annotation by reflection. If it's present, store the class in a List or Set
Aspects won't help you there, because aspects only work on code that's actually executed.
But annotation processing may be an Option, create a Processor that records all annotated classes and creates a class that provides a List of these classes
Well, if your AnnotatedClassRegister.registerClass() doesn't have to be called immediately at AnnotatedClassRegister creation time, but it could wait until a class is first instantiated, then I would consider using a Guice TypeListener, registered with a Matcher that checks if a class is annotated with #MyAnnotation.
That way, you don't need to search for all those classes, they will be registered just before being used. Note that this will work only for classes that get instantiated by Guice.
I would use the staticinitialization() pointcut in AspectJ and amend classes to your register as they are loaded, like so:
after() : staticinitialization(#MyAnnotation *) {
register.registerClass(thisJoinPointStaticPart.getSignature().getDeclaringType());
}
Piece of cake, very simple and elegant.
You can use the ClassGraph package like so:
Java:
try (ScanResult scanResult = new ClassGraph().enableAnnotationInfo().scan()) {
for (ClassInfo classInfo = scanResult.getClassesWithAnnotation(classOf[MyAnnotation].getName()) {
System.out.println(String.format("classInfo = %s", classInfo.getName()));
}
}
Scala:
Using(new ClassGraph().enableAnnotationInfo.scan) { scanResult =>
for (classInfo <- scanResult.getClassesWithAnnotation(classOf[MyAnnotation].getName).asScala) {
println(s"classInfo = ${classInfo.getName}")
}
}

Categories

Resources