Así que estoy jugando con geotools y pensé que sería un proxy de una de sus clases de acceso a datos y rastrear cómo se estaba utilizando en su código.Java.lang.reflect.Proxy devuelve otro proxy de los resultados de la invocación en ClassCastException en la asignación
Codifiqué un proxy dinámico y envolví un FeatureSource (interfaz) en él y lo saqué felizmente. Luego, también quería ver algunos de los objetos transitivos devueltos por el featureSource, ya que lo principal que hace un FeatureSource es devolver un FeatureCollection (FeatureSource es análogo a un sql DataSource y featurecollection a un enunciado sql).
en my invocationhandler Acabo de pasar la llamada al objeto subyacente, imprimiendo la clase/método/argumentos y resultado de destino a medida que avanzaba, pero para las llamadas que devolvieron una FeatureCollection (otra interfaz), envolví ese objeto en mi proxy (la misma clase pero una nueva instancia, ¿no debería importar si lo hiciera?) y lo devolvió. BAM! excepción Classcast:
java.lang.ClassCastException: $Proxy5 cannot be cast to org.geotools.feature.FeatureCollection
at $Proxy4.getFeatures(Unknown Source)
at MyClass.myTestMethod(MyClass.java:295)
el Código de llamada:
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = ... // create the FS
featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) FeatureSourceProxy.newInstance(featureSource, features);
featureSource.getBounds();// ok
featureSource.getSupportedHints();// ok
DefaultQuery query1 = new DefaultQuery(DefaultQuery.ALL);
FeatureCollection<SimpleFeatureType, SimpleFeature> results = featureSource.getFeatures(query1); //<- explosion here
Proxy:
public class FeatureSourceProxy implements java.lang.reflect.InvocationHandler {
private Object target;
private List<SimpleFeature> features;
public static Object newInstance(Object obj, List<SimpleFeature> features) {
return java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new FeatureSourceProxy(obj, features)
);
}
private FeatureSourceProxy(Object obj, List<SimpleFeature> features) {
this.target = obj;
this.features = features;
}
public Object invoke(Object proxy, Method m, Object[] args)throws Throwable{
Object result = null;
try {
if("getFeatures".equals(m.getName())){
result = interceptGetFeatures(m, args);
}
else{
result = m.invoke(target, args);
}
}
catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage(), e);
}
return result;
}
private Object interceptGetFeatures(Method m, Object[] args) throws Exception{
return newInstance(m.invoke(target, args), features);
}
}
¿Es posible volver dinámicamente apoderados de las interfaces de un proxy interfaz o estoy haciendo algo mal? ¡salud!
funciona perfectamente !!wow gracias por eso, en retrospectiva, es obvio que debería haber pensado, por alguna razón, pensé que getInterfaces() devolvería * todas las interfaces implementadas, no solo las implementadas directamente por la clase. – matao