En fait, Vous pouvez construire un tel cadre ou modèle, en utilisant le modèle de proxy. Ici j'explique comment vous pouvez le faire à l'aide de dynamic proxy modèle. L'idée est d',
-
Écrire un gestionnaire de proxy pour obtenir de l'enregistreur et lecteur de procurations de l'API sur demande!
- Écrire une classe wrapper pour stocker vos informations collectées et aussi mettre en oeuvre
hashCode
et equals
méthode de cette classe wrapper pour faciliter la recherche d' Map
comme structure de données.
- Et enfin l'utilisation de l'enregistreur de proxy pour enregistrer et lecteur de proxy pour la relecture de but.
Comment enregistreur fonctionne:
- appelle la vraie API
- recueille les informations appel
- persiste données, prévue dans le contexte de persistance
Comment le lecteur fonctionne:
- Recueillir des informations de la méthode (nom de la méthode, les paramètres)
- Si les informations recueillies matchs avec les informations enregistrées puis retour recueillies précédemment valeur de retour.
- Si la valeur de retour ne correspond pas, persistent les informations collectées (Comme vous voulez).
Maintenant, passons à la mise en œuvre. Si votre API est - MyApi
comme ci-dessous:
public interface MyApi {
public String getMySpouse(String myName);
public int getMyAge(String myName);
...
}
Maintenant, nous allons, d'enregistrement et de relecture de l'invocation de l' public String getMySpouse(String myName)
. Pour faire cela, nous pouvons utiliser une classe pour stocker l'invocation d'informations comme ci-dessous:
public class RecordedInformation {
private String methodName;
private Object[] args;
private Object returnValue;
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
public Object getReturnValue() {
return returnType;
}
public void setReturnValue(Object returnValue) {
this.returnValue = returnValue;
}
@Override
public int hashCode() {
return super.hashCode(); //change your implementation as you like!
}
@Override
public boolean equals(Object obj) {
return super.equals(obj); //change your implementation as you like!
}
}
Maintenant, Voici la partie principale, L' RecordReplyManager
. Cette RecordReplyManager
vous donne un objet proxy de votre API , en fonction des besoins de l'enregistrement ou de lecture.
public class RecordReplyManager implements java.lang.reflect.InvocationHandler {
private Object objOfApi;
private boolean isForRecording;
public static Object newInstance(Object obj, boolean isForRecording) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new RecordReplyManager(obj, isForRecording));
}
private RecordReplyManager(Object obj, boolean isForRecording) {
this.objOfApi = obj;
this.isForRecording = isForRecording;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
if (isForRecording) {
try {
System.out.println("recording...");
System.out.println("method name: " + method.getName());
System.out.print("method arguments:");
for (Object arg : args) {
System.out.print(" " + arg);
}
System.out.println();
result = method.invoke(objOfApi, args);
System.out.println("result: " + result);
RecordedInformation recordedInformation = new RecordedInformation();
recordedInformation.setMethodName(method.getName());
recordedInformation.setArgs(args);
recordedInformation.setReturnValue(result);
//persist your information
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " +
e.getMessage());
} finally {
// do nothing
}
return result;
} else {
try {
System.out.println("replying...");
System.out.println("method name: " + method.getName());
System.out.print("method arguments:");
for (Object arg : args) {
System.out.print(" " + arg);
}
RecordedInformation recordedInformation = new RecordedInformation();
recordedInformation.setMethodName(method.getName());
recordedInformation.setArgs(args);
//if your invocation information (this RecordedInformation) is found in the previously collected map, then return the returnValue from that RecordedInformation.
//if corresponding RecordedInformation does not exists then invoke the real method (like in recording step) and wrap the collected information into RecordedInformation and persist it as you like!
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " +
e.getMessage());
} finally {
// do nothing
}
return result;
}
}
}
Si vous souhaitez enregistrer l'invocation de la méthode, tous vous avez besoin est d'obtenir une API proxy comme ci-dessous:
MyApi realApi = new RealApi(); // using new or whatever way get your service implementation (API implementation)
MyApi myApiWithRecorder = (MyApi) RecordReplyManager.newInstance(realApi, true); // true for recording
myApiWithRecorder.getMySpouse("richard"); // to record getMySpouse
myApiWithRecorder.getMyAge("parker"); // to record getMyAge
...
Et à relire tous vous avez besoin:
MyApi realApi = new RealApi(); // using new or whatever way get your service implementation (API implementation)
MyApi myApiWithReplayer = (MyApi) RecordReplyManager.newInstance(realApi, false); // false for replaying
myApiWithReplayer.getMySpouse("richard"); // to replay getMySpouse
myApiWithRecorder.getMyAge("parker"); // to replay getMyAge
...
Et Vous avez Terminé!
Edit:
Les étapes de base de l'enregistreur et replayers peut être fait au-dessus mentionnés façon. Maintenant son jusqu'à vous, que la façon dont vous souhaitez utiliser ou d'effectuer ces étapes. Vous pouvez faire ce que vous voulez et ce que vous voulez dans l'enregistreur et lecteur de blocs de code et choisissez simplement votre application!