Pregunta

Estoy creando apoderados con ProxyFactory javassist. Al crear un único proxy todo funciona bien.

Sin embargo, al pasar un objeto proxy al mecanismo de proxy, falla con

  

javassist.bytecode.DuplicateMemberException: método duplicado: SetHandler en com.mypackage.Bean _ $$ _ javassist_0 _ $$ _ javassist_1

Estoy creando los proxies con esto:

public Object createProxiedInstance(Object originalInstance) throws Exception {
    Class<?> originalClass = instance.getClass();
    ProxyFactory factory = new ProxyFactory();

    factory.setSuperclass(originalClass);

    factory.setHandler(new MethodHandler() {..});
    Class<T> proxyClass = factory.createClass();

    return proxyClass.newInstance();
}

Entonces, ¿cómo puedo crear proxies de proxy?

Actualización: Los problemas reales es que cada uno de los implementos de proxy la ProxyObject que define método setHandler(..). Por lo que el segundo proxy está tratando de redefinir el método, en lugar de anular en la subclase.

¿Fue útil?

Solución

El problema era (en realidad, es lo mismo con CGLIB - Yo probé usando Commons-proxy) que no debería tratar de crear una clase de proxy de la clase de proxy. El segundo proxy debería volver a ser de la clase original. Por lo que añadir la siguiente línea resuelve el problema:

if (instance instanceof ProxyObject) {
    originalClass = originalClass.getSuperclass();
}

Y un consejo - si se puede usar algún tipo de interceptores (como los definidos en Commons-proxy), hacerlo en lugar de utilizar múltiples servidores proxy

.

Otros consejos

Es una respuesta bastante tarde, pero todavía puede estar interesado en saber esto:

proxies Javassist se implementan con bastante ingenuidad. En el código anterior, Javassist siempre va a crear una clase de proxy con los métodos siguientes:

  1. método A para cualquier método reemplazable de la clase base
  2. dos métodos para (a) obtener un controlador de proxy (getHandler) y (b) establecer un controlador de proxy (setHandler)

Los nombres de los dos últimos métodos están codificados por Javassist y representada por la interfaz de ProxyObject. Si ahora crear una clase de proxy de una clase de proxy, Javassist programaría la creación de métodos de ProxyObject dos veces. Una vez por la primera condición y una vez por la segunda condición.

Se puede evitar esto mediante el establecimiento de un MethodFilter que especifica que no anulan los métodos del ProxyObject tal que javassist no haría sino crear los métodos de la segunda condición. Sin embargo, esto implicaría que ya no se podía establecer un ProxyObject para el proxy súper clase sin tener que acceder directamente al campo correspondiente a través de la reflexión. Por lo tanto, su enfoque es probablemente el más limpio.

cglib define devoluciones de llamada por clase y no por ejemplo de tal manera que este problema con cglib es ligeramente diferente pero los resultados en otro conflicto.

Sin embargo, si desea crear clases de proxy que no sufren estas deficiencias, que podría estar interesado en mi biblioteca Byte de amigos que escribí después de conseguir trabajo frustrado con cglib y javassist cuando se trabaja en casos de esquina. Si está trabajando con la generación de código en tiempo de ejecución espero que podría ayudarle a ofrecer una cierta flexibilidad que las otras bibliotecas carecen.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top