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

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

Traté de usar proxies dynamics, 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?

Como observa, no puede usar proxies dynamics 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" 

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.

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.

Acabo de desarrollar un pequeño marco para este propósito. Puede verificarlo en: http://code.google.com/p/java-interceptor/ (use svn para verificar).

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 . Así que 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.

No hay mucha magia en AspectJ. Puedes escribir tu propio agente. http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html parece ser un buen punto de partida.

  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 dynamics. También es una buena práctica de progtwigción codificar con interfaces y no con clases.

  2. Podría usar Spring framework con las capacidades de Spring AOP (que usan proxies dynamics 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.

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