I have implement a dynamic proxy in order to do some operations before my methods started. now I have a problem when invoking two methods from the proxied class, here is the code:
Dynamic proxy class:
public class IPageProxy implements InvocationHandler {
private Class <? extends IPage> screenClazz;
public IPageProxy(final Class <? extends IPage> screenClazz) {
this.screenClazz = screenClazz;
}
@SuppressWarnings("unchecked")
public static <T extends IPage> T getInstance(final Class<? extends IPage> type)
throws InstantiationException, IllegalAccessException {
List<Class<?>> interfaces = new ArrayList<>();
interfaces.addAll(Arrays.asList(type.getInterfaces()));
return (T) Proxy.newProxyInstance(
type.getClassLoader(),
findInterfaces(type),
new IPageProxy(type)
);
}
static Class<?>[] findInterfaces(final Class<? extends IPage> type) {
Class<?> current = type;
do {
final Class<?>[] interfaces = current.getInterfaces();
if (interfaces.length != 0) {
return interfaces;
}
} while ((current = current.getSuperclass()) != Object.class);
throw new UnsupportedOperationException("The type does not implement any interface");
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws InvocationTargetException,
IllegalAccessException, IllegalArgumentException, InstantiationException, ParserConfigurationException, XPathExpressionException, NoSuchFieldException, SecurityException {
// before method executed this code will be done
System.out.println("* Dynamic proxy invoke method executed for " + method.getName());
// Invoke original method
return method.invoke(screenClazz.newInstance(), args);
}
}
Main class:
public static void main(String[] args) {
try {
//IEventDesignDialog a = new EventDesignDialog();
IEventDesignDialog a = (IEventDesignDialog)getInstance(EventDesignDialog.class);
a.getEventType().getShow();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public static <T extends IPage> T getInstance(final Class<? extends IPage> type) throws InstantiationException, IllegalAccessException {
return (T) IPageProxy.getInstance(type);
}
Proxied class:
public class EventDesignDialog implements IEventDesignDialog{
private String show;
private String dateAndTimeDisplayFormat;
private String eventType;
@Entity(visibileName = "Show")
public IEventDesignDialog getShow() {
System.out.println("get show method invokde successfully");
return this;
}
@Entity(visibileName = "Date And Time display format")
public IEventDesignDialog getDateAndTimeDisplayFormat() {
System.out.println("get date and time display format method invokde successfully");
return this;
}
@Entity(visibileName = "Event Type")
public IEventDesignDialog getEventType() {
System.out.println("get event type method invokde successfully");
return this;
}
}
Actual output:
*** Dynamic proxy invoke method executed for getEventType
get event type method invokde successfully
get show method invokde successfully**
as shown invoke method executed only at the first method invocation after initializing the proxy, second method invoked directly, without proxy functionality is done.
my goal is to execute invoke method each time a method appears at my collection is invoked, the expected result should be as shown below.
Expected output:
*** Dynamic proxy invoke method executed for getEventType
get event type method invokde successfully
* Dynamic proxy invoke method executed for getShow
get show method invokde successfully**
please let me know if more explanations needed.
I have solve this issue by creating an Interface with default method that return proxy instance, then returned it after executing the invoked method functionality:
updated code:
My Page Interface:
My Page class:
main class:
IProxy Page stay the same without changes.