java - 如何将存储在 mongodb 中的 getter 方法用于其他 POJO 类?
问题描述
我有一个类具有 getter 和 setter 方法,我将该 getter 方法与其他一些集合一起存储在 mongodb 中。从数据库获取方法名称后如何访问该方法。是否可以这样做?
public class MappingAlgorithmScoreGenerationRules {
@Field(value = FieldNames.CATEGORY)
private String category;
@Field(value = FieldNames.ATTRIBUTE_NAME)
private MappingScoreGenerationLogic attributeName;
@Field(value = FieldNames.PRIORITY)
private Integer priority;
@Field(value = FieldNames.ATTRIBUTE_SCORE)
private Integer attributeScore;
@Field(value = FieldNames.FINAL_THRESHOLD)
private Integer finalThreshold;
@Field(value = FieldNames.RESULT_COUNT)
private Integer resultCount;
@Field(value = FieldNames.NORMALIZED_VALUE)
private Integer normalizedValue;
@Field(value = FieldNames.GETTER_METHOD)
private String getterMethod;
}
这是我存储方法名称的类。
public class MatchEntry {
private double matchedWeight;
public double getMatchedWeight() {
return matchedWeight;
}
public void setMatchedWeight(double matchedWeight) {
this.matchedWeight = matchedWeight;
}
}
getMatchedWeight 是我要存储在 DB MappingAlgorithmScoreGenerationRules 中的方法名称。
获取方法名后如何访问方法名?我想访问例如:MatchEntry.(the value get from db)
解决方案
在 Java 中,您可以使用反射 ( https://docs.oracle.com/javase/tutorial/reflect/member/methodInvocation.html )按名称实现方法访问。这是一个教程,您可以使用它来更多地了解此语言功能:https ://www.geeksforgeeks.org/reflection-in-java/
在您的示例中,假设您已经MappingAlgorithmScoreGenerationRules
从数据库加载了一个实例,其getterMethod
属性返回“getMatchedWeight”。我们还假设您有一个MatchEntry
.
然后,您将访问如下:
MappingAlgorithmScoreGenerationRules rules = ....; //load from DB
MatchEntry entry = ...; //wherever it comes from
String getterMethodName = rules.getGetterMethod();
Method getter = MatchEntry.class.getMethod(getterMethodName);
Object value = getter.invoke(entry);
此代码片段省略了异常,特别是NoSuchMethodException
和InvocationTargetException
.
请注意,如果您选择这种方法,并且很大程度上取决于您的域模型的其余部分,您还需要非常小心对实际值的返回类型的假设(除非您可以以某种方式保证它们都是相同的,在这种情况下,您可以转换该值)。
使用反射的代码本身也很脆弱,一旦重构就容易失败。想象一下,您有一个包含这些规则的填充数据库,并且在代码审查期间,一些方法被重命名。无意义的变化?或者您的整个设置会在下一次部署时中断?
一种(类型)更安全的方法可能是确保所有条目和相关对象都从标准化getValue(String attributeName)
方法返回类型的接口派生,因此您可以这样做而不是弄乱反射:
MappingAlgorithmScoreGenerationRules rules = ....; //load from DB
MatchEntry entry = ...; //wherever it comes from
String attributeName = rules.getAttribute(); //instead of 'getterMethod'
Object value = entry.getValue(attributeName);
其中 MatchEntry.getValue 可能定义为:
public Object getValue(String attribute) {
switch(attribute) {
case "matchedWeight": return getMatchedWeight();
default: return null; //or you could throw an exception
}
}
这将很容易在任何类型的方法名称重构和重组中幸存下来,但会增加为每个新属性添加 case 到 switch 的开销。
这个问题可以通过运行时注释部分解决,该注释本质上将属性名称绑定到 getter 方法,例如:
public class MatchEntry implements Matchable {
private double matchedWeight;
@MyCustomAnnotation("matchedWeight")
public double getMatchedWeight() {
return matchedWeight;
}
public void setMatchedWeight(double matchedWeight) {
this.matchedWeight = matchedWeight;
}
}
public interface Matchable {
default Object getValue(String attributeName) {
//read methods annotated with 'MyCustomAnnotation's in current class and call the one with matching value
}
}
您的getValue(String attributeName)
任务是阅读这些注释并动态确定要调用的 getter。仍然需要在需要的任何地方添加注释,但至少它与 getter 一起使用,而不是隐藏在可能跨多个类定义重复的某个开关中。相反,您只需要在父界面中有一个默认定义,如上所示。
推荐阅读
- html - 透明边框图像翻转底层背景颜色的渐变?
- charts - 谷歌表 - 价格图表演示
- makefile - 检查 makefile 中的 ifeq 变量
- python - google-speech API 转录响应重复多次
- postgresql - 双 Postgres 实例 config_file 问题
- r - 查找函数中使用的函数
- azure-data-factory - 使用 Azure 数据工厂加载数据时出现问题
- c# - ReSharper 错误地声称 IDictionary.Values 始终为非空
- python - 如何在 Python 中清除 ssh 下子进程的标准输出?
- c# - ClipToBounds 没有边框颜色问题 - Xamarin.iOS,C#