Hi I have a strategy pattern in a spring boot application. All my strategies have autowired constructors. I am new to spring boot. I do not have a simplest of idea how am I going to write my factory for strategy classes as autowired constructors have injected dependencies. I appreciate any help I get with this.
NOTE: I am leaving out out Intefaces and base classes to not to clutter sample.
public class StrategyA implement Strategy {
private DependencyA depA;
private DependencyB depB;
@Autowired
public StragegyA(DependencyA depA, DependencyB depB) {
this.depA = depA;
this.depB = depB;
}
}
public class StrategyB implements Strategy {
private DependencyA depA;
private DependencyB depB;
@Autowired
public StragegyB(DependencyA depA, DependencyB depB) {
this.depA = depA;
this.depB = depB;
}
}
public class StrategyFactory {
public Strategy getStrategy(String strategyName) {
if (name.equals("StrategyA")) {
<b>return StrategyA; //My problem is here
} else {
return StrategyB; // And Here
}
}
}
All the previous answers are using a pretty straight forward usage of spring DI. However it's also possible to use ServiceLocatorFactoryBean in order to create a factory without having to specify any bean in the factory. First define a interface for your factory:
Then in your application:
Now you can define bean (using annotation @Service, @Component or @Bean) that implements/extends and they are automatically registered into the MyFactory bean and can be created with:
The best part is you can register the Strategy bean as lazy and with different scopes.
Make your StrategyFactory another Spring bean, and inject all the strategies in the factory:
I usually use an enum rather than a String to identify the stratehy, and I make each Strategy return the enum value that it handles, so the iteration can be as simple as
Of course, you can also store the strategies in a Map inside the constructor, to make the lookup O(1).
I would suggest you to make your
StrategyFactory
a bean and inject into it aMap<String, Strategy>
. Spring fill it with the name of the strategy bean as a key and a value will be a strategy itself. Then all you'll need to do is to callget
on thatMap
.Here is an example:
Prints:
Use the same approach with autowiring all the strategies