背景
関連コード
FnConverter
package com.example.demo.bean;
import com.example.demo.entity.ValidatedRequestVO;
/**
*
* @description
* @date 7/ 7:20 PM
*/
public class FnConverter<F, T> {
/**
* 入力メソッドがフィールド名を返す
*
* @param fn
* @return
*
* @date 7/ 7:32 PM
*/
public String fnToFieldName(IFn<F, T> fn) {
return Reflections.fnToFieldName(fn);
}
/**
* メソッドを渡してメソッド名を返す
*
* @param fn
* @return
*
* @date 7/ 7:32 PM
*/
public String fnToFnName(IFn<F, T> fn) {
return Reflections.fnToFnName(fn);
}
/**
* 受信メソッドの戻り値アノテーション
*
* @param fn
* @return mongo
*
* @date 7/ 7:32 PM
*/
public String fnToMongoName(IFn<F, T> fn) {
return Reflections.fnToMongoName(fn);
}
public static void main(String[] args) {
FnConverter<ValidatedRequestVO, Object> fnConverter = new FnConverter();
String fieldName = fnConverter.fnToFieldName(ValidatedRequestVO::getStr);
System.out.println("フィールド名" + fieldName);
String fnName = fnConverter.fnToFnName(ValidatedRequestVO::getStr);
System.out.println("メソッド名" + fnName);
FnConverter<String, Object> fnConverter2 = new FnConverter();
String fieldName2 = fnConverter2.fnToFieldName(new ValidatedRequestVO()::setStr);
System.out.println("フィールド名" + fieldName2);
String fnName2 = fnConverter2.fnToFnName(new ValidatedRequestVO()::setStr);
System.out.println("メソッド名" + fnName2);
FnConverter<ValidatedRequestVO, Object> fnConverter3 = new FnConverter();
String fieldName3 = fnConverter3.fnToMongoName(ValidatedRequestVO::getStartDate);
System.out.println("フィールド名" + fieldName3);
}
}
IFn
package com.example.demo.bean;
import java.io.Serializable;
/**
* F 入力型、戻り値型
*
*/
@FunctionalInterface
public interface IFn<F, T> extends Serializable {
T apply(F source);
}
リフレクションズ
package com.example.demo.bean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.mapping.Field;
import java.beans.Introspector;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
/**
* メソッドを渡した後にロジックを実装する
*
*
* @date 7/ 7:20 PM
*/
@Slf4j
public class Reflections {
private Reflections() {
}
public static String fnToFieldName(IFn fn) {
try {
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
String getter = serializedLambda.getImplMethodName();
String fieldName = "";
if (getter.startsWith("get")) {
fieldName = Introspector.decapitalize(getter.replace("get", ""));
} else {
fieldName = Introspector.decapitalize(getter.replace("set", ""));
}
return fieldName;
} catch (ReflectiveOperationException e) {
log.warn(String.format("%s:%s",
Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage()), e);
}
return "";
}
public static String fnToFnName(IFn fn) {
try {
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
return serializedLambda.getImplMethodName();
} catch (ReflectiveOperationException e) {
log.warn(String.format("%s:%s",
Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage()), e);
}
return "";
}
public static String fnToMongoName(IFn fn) {
try {
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(fn);
String getter = serializedLambda.getImplMethodName();
String fieldName = "";
if (getter.startsWith("get")) {
fieldName = Introspector.decapitalize(getter.replace("get", ""));
} else {
fieldName = Introspector.decapitalize(getter.replace("set", ""));
}
Field field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName).getAnnotation(Field.class);
return field == null ? fieldName : field.value();
} catch (ReflectiveOperationException e) {
log.warn(String.format("%s:%s",
Thread.currentThread().getStackTrace()[1].getMethodName(), e.getMessage()), e);
}
return "";
}
}
アプリケーション例
- ビデオで紹介されているように、メソッド/フィールドを取ることができるアノテーション
- 反射を利用した擬似プロキシ
- 最も一般的なアプリケーションはmybatisPlusで、SQLを変更することなく、必要なフィールドや不要なフィールドを動的に渡すことができ、パフォーマンスを最適化できます。