I have an interface which extends java.util.function.Function
, there are 2 further implementation of the interface lets say class A, B which implements the interface Base;
interface Base extends Function<Object, Object> {
@Override
default Object apply(Object object) {
return object; // simply do nothing
}
default boolean accept(String str) {
return true; // for choosing the right instance
}
}
@Service
class A implements Base {
String validationString = "some-random-string";
@Override
public Object apply(Object object) {
// update the object ....
return object;
}
@Override
public boolean accept(String str) {
return str.equals(validationString);
}
}
@Service
class B implements Base {
String validationString = "some-random-string-2";
@Override
public Object apply(Object object) {
// update the object ....
return object;
}
@Override
public boolean accept(String str) {
return str.equals(validationString);
}
}
@Service
@RequiredArgsConstructor
class SomeService {
List<Base> baseList;
public void callingClass(String str) {
// in below
// I want to order it in such a way that
// if str matches A.validationString then give back A's instance
// else if str matches B.validationString then give back B's instance
// else return Base's instance
Base base = baseList.stream()
.filter(baseImpl -> baseImpl.accept(str))
.findFirst().orElseThrow();
}
}
So, what I am trying to achieve, if there is any way from which I don't have to manually create a Factory Class (Factory Pattern) and dynamically Filter the instance A, B using accept() and if none find then return instance of Base (as default).
Can anybody help with this?
Combining @k314159 and @atish.s solution and improving on that:
Expose the DefaultBase class as another bean, but add @Order annotation to put it last in list
@Component
@Order(Precedence.LAST)
class DefaultBase implements Base {
default accepts(Object obj){
return true;
}
}
Then changing the Service method to this:
public Base callingClass(String str) {
return baseList.stream()
.filter(baseImpl -> baseImpl.accept(str))
.findFirst()
.orElseThrow();
}