without method from example dynamically java reflection methods

from - method invoke java reflection example



¿Cómo puedo interceptar una invocación a un método con funciones Java estándar(sin AspectJ, etc.)? (8)

Quiero interceptar todas las invocaciones de métodos a alguna clase MyClass para poder reaccionar en algunas invocaciones de setter.

Intenté usar proxies dinámicos, pero hasta donde yo sé, esto solo funciona para las clases que implementan alguna interfaz. Pero MyClass no tiene esa interfaz.

¿Hay alguna otra manera, además de implementar una clase contenedora, que delegue todas las invocaciones a un miembro, que es una instancia de MyClass o incluida mediante AOP?


  1. ¿Por qué su clase no puede implementar una interfaz? Podrías extraer alguna interfaz que contenga todos los métodos que quieras interceptar y usar fácilmente el mecanismo de proxies dinámicos. También es una buena práctica de programación codificar con interfaces y no con clases.

  2. Podría usar Spring framework con las capacidades de Spring AOP (que usan proxies dinámicos en su interior) para hacerlo. Simplemente tendrá que definir su clase como Spring Bean en el archivo de configuración y los clientes de su clase tendrán que obtener su instancia del contexto de la aplicación Spring o como una dependencia automáticamente (definiendo el método setMyClass (MyClass mc) por ejemplo ) Desde allí, puede ir fácilmente a la definición de un aspecto que intercepta todas las llamadas a métodos de esta clase.


Algunos de los gurús de Java podrían fruncir el ceño ante esto, pero he tenido un buen éxito al evitar los tipos primitivos y los setters en conjunto. Mi clase se ve así:

class Employee extends SmartPojo { public SmartString name; public SmartInt age; }

Notarás dos cosas: 1. todo es público. 2. Sin constructor.

La magia ocurre en SmartPojo que busca cualquier campo que implemente la interfaz "Inteligente" y la inicializa. Como esto no es primitivo (y no hay una clase final), puedo agregar los métodos set () y get () para todos los campos en cualquier lugar de mi modelo en un solo lugar . Entonces, ya no se pierden setter / getter, es increíblemente simple agregar notificaciones (también en un solo lugar), etc.

Cierto, este ya no es POJO y no es un frijol en la mayoría de los sentidos, pero he descubierto que estas viejas ideas me limitan más de lo que me ayudan. YMMV.



Java no tiene características de lenguaje real para la interceptación de métodos (no está seguro de que haya ningún lenguaje estático)

Me gusta un poco la idea de Nick de usar la interfaz del depurador, eso es simplemente malo.

Creo que la respuesta corta que necesita es: No, no hay una forma de interceptar una llamada a un método en Java sin reemplazar realmente la clase utilizando un proxy o un contenedor.

Nota: Las bibliotecas de AOP solo hacen que esto suceda automáticamente.



Como observa, no puede usar proxies dinámicos JDK (sin interfaz), pero utilizando Spring y CGLIB (JAR incluido con Spring), puede hacer lo siguiente:

public class Foo { public void setBar() { throw new UnsupportedOperationException("should not go here"); } public void redirected() { System.out.println("Yiha"); } } Foo foo = new Foo(); ProxyFactory pf = new ProxyFactory(foo); pf.addAdvice(new MethodInterceptor() { public Object invoke(MethodInvocation mi) throws Throwable { if (mi.getMethod().getName().startsWith("set")) { Method redirect = mi.getThis().getClass().getMethod("redirected"); redirect.invoke(mi.getThis()); } return null; } }); Foo proxy = (Foo) pf.getProxy(); proxy.setBar(); // prints "Yiha"


Para la interceptación de la invocación del método java, una AspectJ es una buena herramienta para usar. A través de la cual se pueden interceptar llamadas, ejecuciones, etc. de manera eficiente. Estoy usando la misma herramienta para interceptar llamadas a métodos java. Podemos aplicar puntos de corte y aspectos para interceptar cualquier llamada al método java. por mera información lea esto


Si estás preparado para hacer algo realmente feo, echa un vistazo a:

http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/

Básicamente, la interfaz del depurador debería permitirle adjuntar como un depurador y, por lo tanto, interceptar llamadas. Ten en cuenta que creo que esta es una idea realmente mala, pero preguntaste si era posible.