Instantiate proper strategy with Java and Spring Boot - java

I have the following situation:
I have to validate a Token using (for now) 2 different strategies, they both do the same thing (check if the token is valid) but in different ways.
My current way of dealing with the strategy instantiation looks like this:
#Service
public class ValidationService {
private Map<ValidationType, ValidationStrategy> validationMap = new HashMap<>();
public ValidationService() {
validationMap.put(ValidationType.A, new AValidationStrategy());
validationMap.put(ValidationType.B, new BValidationStrategy());
}
public void validate(ValidationType type, String token) {
ValidationStrategy strategy = validationMap.get(type);
if(strategy == null) {
strategy = new NoValidationStrategy();
}
strategy.validate(token);
}
}
My question is: Is there a prettier way to set up the proper validation according to the ValidationType enum? Because the constructor would grow more and more as new validation strategies would be added in the system.
I thought that maybe I could keep that Map<> variable and add new Strategy instances when the ValidationService bean would be created by some sort of Spring Boot configuration, but I don't know how I could access the Bean after its instantiation by Spring Boot.
Help me out if you have a better way of doing this! :)
PS: Any code snippets or useful links would be greatly appreciated!

Absolutely, one option is Reflection. Every ValidationStrategy could define a ValidationType either as a Method or through an Annotation, assuming ValidationType is an enumeration. You could then find all ValidationStrategy and group them to a Map based on type. This would solve the problem of having to update the map every time a new validation strategy is added.

Related

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

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();
}}
}

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.

Map a collection with parameter with mapstruct

To map a certain object with mapstruct I need some custom post processing which needs an additional parameter to do it's work:
#Mapper
public abstract class AlertConfigActionMapper {
#Mappings({ #Mapping(target = "label", ignore = true)})
public abstract AlertConfigActionTO map (AlertConfigAction action, Locale userLanguage);
#AfterMapping
public void setLabel (AlertConfigAction action, #MappingTarget AlertConfigActionTO to, Locale userLanguage) {
for (AlertConfigActionLabel label : action.getAlertConfigActionLabels()) {
if (label.getLanguage().equals(userLanguage)) {
to.setLabel(label.getLabel());
break;
} else if (label.getLanguage().equals(Locale.ENGLISH)) {
to.setLabel(label.getLabel());
}
}
}
}
This works just fine.
The problem starts when I add following method to this mapper:
public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, Locale userLanguage);
I need to pass this parameter (userLanguage) as well but mapstruct seems to 'break down' in this case: I generates following code for this part (which naturally gives a compilation error):
#Override
public List<AlertConfigActionTO> mapList(List<AlertConfigAction> actions, Locale userLanguage) {
if ( actions == null && userLanguage == null ) {
return null;
}
List<AlertConfigActionTO> list = new List<AlertConfigActionTO>();
return list;
}
I'm sure it is related to the parameter since if I remove it (from all mapping methods) then the mapList method is generated correctly.
What is needed to be done to allow custom parameters in this case?
What you describe is not possible (yet). Could you open a feature request in our issue tracker? We should provide means of denoting parameters as some sort of "context" which is passed down the call stack.
As a work-around for the time being, you might take a look at using a ThreadLocal which you set before invoking the mapping routine and which you access in your after-mapping customization. It's not elegant - and you need to make sure to clean up the thread local to avoid memory leaks - but it should do the trick.
I know that this question is quiet old, but I run into this issue, and starting at version 1.2 of mapstruct you can resolve it using #Context
So declaring the mapping for the list need to be like this :
public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, #Context Locale userLanguage);
Now, you juste need to add another non abstract mapping like this :
public AlertConfigActionTO mapConcrete (AlertConfigAction action, #Context Locale userLanguage){
return map (action, userLanguage);
}
I don't think it is possible. At least not that way. Problem is that you prepare interface/abstract class - and rest is done by the engine. And that engine expects methods with one parameter... There are decorators, but they go the same way. I would try to inject language. Create bean, mark it as session scoped, and find out. With Spring, you would use ScopedProxyMode for that... Not sure how that goes with CDI.
Other option is more workaround, then solution - maybe that AlertConfigAction can pass that information?

Designing a mutable complex class and its construction in java

I am designing a complex Configuration class as part of an API design. The Configuration class roughly looks like this.. (I ignored generics/access modifiers etc)
class Configuration {
One obj1;
Two obj2;
}
class One {
List<Double> values;
}
class Two {
double value;
Map<String, Double> data;
}
This is what I want to accomplish:
I want users to be able to create this Configuration class the first time easily and submit to server.
Then they can change any part of this class and send the updated configuration to the server.
What design patterns to use and avoid?
Is it better to make this class Immutable and use builder pattern?
Or just provide all kinds of modification methods On Configuration class so they can modify the same Configuration class (at all levels) in-place without having to create a new Configuration class for every update. I think Builder pattern is good for Immutable classes only.
Questions:
Is there any way to exploit Builder pattern for this type of scenarios?
Or is it better to provide mutator methods on Configuration class like I mentioned above?
Or are there any other better patterns available?
I think you should use prototype pattern:
in your code you can add map that hold all types of configurations
the map will have a key called "currentConfiguration" and the value will be the configuration that should be loaded. the map can also contains other configurations that can be stored in the map and can replace the current configuration if needed.
once you fetch configuration from the map you simply clone the configuration object and the user can do what ever he pleased with that. after the changes he can save the configuration in the map with speicifc name. so the user can get configuration object that is quite close that what he needs and configure it accordingly.
the code should look like this:`public class CloudRepository {
private Map<String, Configuration> rep;
public CloudRepository(Configuration current){
rep = new HashMap<String, Configuration>();
rep.put("current", current);
}
public Configuration getConfiguration(String string){
return (Configuration) rep.get(string).clone();
}
public void addConfiguration(String name, Configuration conf){
rep.put(name, conf);
}
public void replaceCurrentConfiguration(Configuration conf){
rep.put("current", conf);
}
}
you can also write more code to handle history for your configurations.
you can also consider making this class singleton

Canonicalizing Java bean property names

I have a bunch of third-party Java classes that use different property names for what are essentially the same property:
public class Foo {
public String getReferenceID();
public void setReferenceID(String id);
public String getFilename();
public void setFilename(String fileName);
}
public class Bar {
public String getRefID();
public void setRefID(String id);
public String getFileName();
public void setFileName(String fileName);
}
I'd like to be able to address these in a canonicalized form, so that I can treat them polymorphically, and so that I can do stuff with Apache BeanUtils like:
PropertyUtils.copyProperties(object1,object2);
Clearly it would be trivial to write an Adapter for each class ...
public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
return this.delegate.getRefID();
}
// etc.
}
But I wonder is there something out there more generalized and dynamic? Something that would take a one-to-many map of property name equivalences, and a delegate class, and produce the Adapter?
I've never used it, but I think you're looking for Dozer:
Dozer is a Java Bean to Java Bean mapper that recursively copies data
from one object to another. Typically, these Java Beans will be of
different complex types.
Dozer supports simple property mapping, complex type mapping,
bi-directional mapping, implicit-explicit mapping, as well as
recursive mapping. This includes mapping collection attributes that
also need mapping at the element level.
Dozer not only supports mapping between attribute names, but also
automatically converting between types. Most conversion scenarios are
supported out of the box, but Dozer also allows you to specify custom
conversions via XML.
First Option is Dozer.
Second option is Smooks Framework
with a tweak. It will be beneficial to use Smook's Graphical mapper.
Another option would be XStream with custom Mapper.
maybe something like that:
public class CanonicalizedBar implements CanonicalizedBazBean {
public String getReferenceID() {
Method m = this.delegate.getClass().getDeclaredMethod("getReferenceID");
if(m == null)
m = this.delegate.getClass().getDeclaredMethod("getRefID");
...
return m.invoke();
}
// etc.
}
Although, I personally have never used it. I noticed that a project called orika is noted as having the best performance and the ability to automatically understand many such mappings.
At any rate it also supports custom mappings and uses generated code to implicitly define the adapters.
You can also define a custom mapper, that is if you know how to canonize the member names you can use that knowledge to build a mapping that is true for all your objects. for instance:
DefaultFieldMapper myDefaultMapper = new DefaultFieldMapper() {
public String suggestMapping(String propertyName, Type<?> fromPropertyType) {
// split word according to camel case (apache commons lang)
String[] words= StringUtils.splitByCharacterTypeCamelCase(propertyName);
if(words[0].length() > 6) {
// trim first camel-cased word of propery name to 3 letters
words[0]= words[0].substring(0,2);
return StringUtils.join(words);
} else {
// remains unchanged
return propertyName;
}
}
}
mapperFactory.registerDefaultFieldMapper(myDefaultMapper );
I haven't done much with it but you may be able to use Aspect Oriented Programming to do this.
What you should be able to do I think is add a method to each of the classes that internally calls the real method. See this article about half way down it talks about mixins.
AspectJ is probably the most popular implementation.

Categories

Resources