作为集成的核心服务的一部分,我有一些自动生成的类(模型)。但是,这些类的作者有意/无意地保留了 toString 方法的替代。
我对如何使用这些类有一些选择,对此我需要一些了解。
我可以在包中覆盖这些类的完全相同的副本,从而覆盖 toString 方法,并在.gitignore中添加这些自动生成的类。但是,使用此方法的注意事项是,这些类中的任何将来更改都不会反映在我的代码中,新开发人员可能会忽略服务和我的实现中的不兼容性。
我可以为顶级类创建一个包装器类,并添加toString,但是随后我必须为每个方法调用getter,如果它包含嵌套类,则可能导致某种平面图创建。 (混乱的 toString方法)
我当时正在考虑使用装饰器模式(将功能添加到类中而不破坏它),但是我不确定这是否是打算使用的方式。
我很肯定自己不是第一个遇到此问题的人,因此必须采取某种 正确的方法 来解决该问题。朝这个方向轻推会有所帮助。
编辑
到目前为止,我已经观察到唯一的方法是更改字节码或使用反射。但是,更改字节码只会解决受影响的类的问题,而不会影响所有(将来的)类。
相反,我编写了一个实现 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);
}