У меня есть несколько автоматически сгенерированных классов (моделей) как часть основной службы, которую я интегрирую. Однако авторы этих классов намеренно / непреднамеренно оставили переопределение метода toString .
У меня есть несколько вариантов использования этих классов, о которых мне нужно кое-что понять.
Я могу сделать точные копии этих классов в моих пакетах, переопределяя метод toString , и добавить эти автоматически созданные классы в .gitignore. Однако, предостережение при таком подходе заключается в том, что любые будущие изменения в этих классах не будут отражены в моем коде, и новые разработчики могут не заметить несовместимость в службе и моей реализации.
Я могу создать класс-обертку для классов верхнего уровня и добавить toString, но затем мне придется вызывать методы получения для каждого отдельного метода, и если он содержит вложенные классы, которые могут привести к созданию плоской карты. (Хаотический метод toString)
Я думал об использовании шаблона декоратора (добавляя функциональность в класс, не нарушая его), но я не уверен, что именно так он и предназначен.
Я уверен, что я не первый, кто столкнулся с этой проблемой, поэтому должен быть какой-то правильный путь , чтобы заняться этим. Смещение в этом направлении было бы полезно.
EDIT
До сих пор я заметил, что единственный способ - это изменить байт-код или использовать отражение. Тем не менее, изменение байт-кода будет исправлено только для классов, затронутых не для всех (будущих) классов.
Вместо этого я написал собственный регистратор, который реализует org.slf4j.Logger и отменяет ведение журнала информационного уровня так, что он:
Ведет себя одинаково для всех объектов, имеющих метод toString
переопределен
Разбирает объект в Json с использованием библиотеки Джексона и объединяет этот Json в строку
предоставленный аргумент
Хотя Джексон внутренне использует отражение для преобразования pojo в json, я делаю это только в тех случаях, когда у меня нет myobject.toString ().
Вот реализация моего собственного регистратора.
public class MeinLogger implements Logger {
private static final String REGEX_CURLY = "\\{}";
private static final String TO_STRING = "toString";
private static final String CURLY_ALTERNATE = "REGEX_CURLY";
private final Logger superLogger;
private ObjectMapper objectMapper;
public MeinLogger(Class<?> className) {
this.objectMapper = new ObjectMapper();
this.superLogger = LoggerFactory.getLogger(className);
}
@Override
public void info(String s) {
}
@Override
public void info(String s, Object o) {
boolean toStringImplemented = false;
try {
if(checkToStringAndReturn(o).equalsIgnoreCase(CURLY_ALTERNATE))
toStringImplemented = true;
s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(o));
} catch (NoSuchMethodException | JsonProcessingException e1) {
e1.printStackTrace();
}
s = s.replaceAll(CURLY_ALTERNATE, REGEX_CURLY);
if(toStringImplemented) {
superLogger.info(s, o);
} else {
superLogger.info(s);
}
}
@Override
public void info(String s, Object o, Object o1) {
List<Object> implementedClasses = new ArrayList<>();
try {
if(checkToStringAndReturn(o).equalsIgnoreCase(CURLY_ALTERNATE))
implementedClasses.add(o);
s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(o));
if(checkToStringAndReturn(o1).equalsIgnoreCase(CURLY_ALTERNATE))
implementedClasses.add(o1);
s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(o1));
} catch (NoSuchMethodException | JsonProcessingException e) {
e.printStackTrace();
}
s = s.replaceAll(CURLY_ALTERNATE, REGEX_CURLY);
if(implementedClasses.size() > 0)
superLogger.info(s, implementedClasses.toArray(new Object[0]));
else
superLogger.info(s);
}
@Override
public void info(String s, Object... objects) {
List<Object> implementedClasses = new ArrayList<>();
for (Object obj : objects) {
try {
if(checkToStringAndReturn(obj).equalsIgnoreCase(CURLY_ALTERNATE))
implementedClasses.add(obj);
s = s.replaceFirst(REGEX_CURLY, checkToStringAndReturn(obj));
} catch (NoSuchMethodException | JsonProcessingException e1) {
e1.printStackTrace();
}
}
s = s.replaceAll(CURLY_ALTERNATE, REGEX_CURLY);
if(implementedClasses.size() > 0)
superLogger.info(s, implementedClasses.toArray(new Object[0]));
else
superLogger.info(s);
}