Я нашел еще лучшее решение
Используйте объект CDI.current ():
class TestClass {
@Inject
ClassnameCollection collection; // Inject
void doSth(classsuffix) throws Exception {
dynamicObject = CDI.current().select(
(Class<TestInterface>) Class.forName("org.test.Classname" + suffix)).get();
dynamicObject.doStuff();
}
}
Пример класса для справки:
public class ClassnameOne implements TestInterface {
@Inject
private Logger log;
// ...
@Override
public void doStuff() {
// Do stuff
log.info("done");
}
}
С этимРешение: нет необходимости вносить какие-либо изменения в существующие классы или что-то в этом роде.
Старая версия
Лучшее решение, которое я мог бы найти, это что-то вроде этого:
Создатьколлекция всех доступных классов:
public class ClassnameCollection {
@Inject
public ClassnameOne classnameOne;
@Inject
public ClassnameTwo classnameTwo;
// ...
}
И вставьте его в нужный класс динамического класса:
class TestClass {
@Inject
ClassnameCollection collection; // Inject
void doSth(classsuffix) throws Exception {
Class collectionClass = ClassnameCollection.class;
Field collectionField = collectionClass.getDeclaredField("classname" + suffix); // Get the declared field by String
TestInterface dynamicObject = (TestInterface) collectionField.get(collection); // There you have the dynamic object with all the subclasses (for example Logger) initialized
dynamicObject.doStuff();
}
}
Пример класса для справки:
public class ClassnameOne implements TestInterface {
@Inject
private Logger log;
// ...
@Override
public void doStuff() {
// Do stuff
log.info("done");
}
}
Честно говоря, я считаю, что это наилучшее из возможных решений, поскольку оно не меняет ни один из подклассов, и его поддержка довольно проста (просто добавьте новый Inject
в класс ClassnameCollection
).