2014-08-29 10 views
5

W CDI 1.2 istnieje sposób sprawdzenia, czy instancja klasy jest proxified? Potrzebuję tego, ponieważ muszę uzyskać nazwę oryginalnej klasy, a nie nazwę proxy.Sprawdzanie, czy klasa jest proxified z CDI 1.2

@Inject Bean bean; 

public void sysout() { 
    // will print something like com.Bean$$Weld9239823 
    System.out.println(bean.getClass()); 

    // I don't know how to check if the bean instance if a proxy or real class instance 
} 

Korzystanie z klas spoiny mogę zrobić to zadanie:

public void sysout() { 
    // will print true because this is a proxy 
    System.out.println(ProxyObject.class.isAssignableFrom(bean)); 

    // will print com.Bean 
    System.out.println(((TargetInstanceProxy) bean).getTargetInstance()); 
} 

W CDI 1.1 nie ma sposobu, aby to zrobić. Przeszukuję dokumentację CDI 1.2, jeśli została do tego dodana metoda, ale niczego nie znalazłem.

Więc ... Tęsknię za czymś i CDI 1.2 jest metoda uzyskania oryginalnej nazwy klasy i instancji? A jeśli nie, istnieje równina, aby dodać tę funkcję w pobliżu funkcji?

+1

Jaka jest użyteczność przy ustalaniu klasy ziarna? Biorąc pod uwagę, że wstrzykujesz "fasolkę fasoli", wiesz już, że implementuje "fasolę" –

+0

Czy wypróbowałeś to rozwiązanie? http://stackoverflow.com/a/7504552/2492784 – Sven

Odpowiedz

0

To jest straszny hack, ale dla Weld (i prawdopodobnie innych implementacji) możesz sprawdzić, czy nazwa klasy zawiera "Proxy": possibleProxy.getClass().getSimpleName().contains("Proxy"). Używam go tylko w celach logowania, aby uzyskać oczyszczony się wersję zawiniętego nazwą klasy:

/** 
* Get the actual simple name of the objects class that might be wrapped by 
* a proxy. A "simple" class name is not fully qualified (no package name). 
* 
* @param possibleProxy an object that might be a proxy to the actual 
* object. 
* @return the simple name of the actual object's class 
*/ 
public static String getActualSimpleClassName(final Object possibleProxy) { 
    final String outerClassName = possibleProxy.getClass().getSimpleName(); 
    final String innerClassName; 
    if (outerClassName.contains("Proxy")) { 
     innerClassName = outerClassName.substring(0, outerClassName.indexOf('$')); 
    } else { 
     innerClassName = outerClassName; 
    } 
    return innerClassName; 
} 
0

można dokonać metodę wewnątrz zastępowanym cdi fasoli jak

public String getClassName() { 
    return this.getClass().getName(); 
} 

nie jest to najlepsze rozwiązanie , ale prosty pragmatyczny sposób, aby uzyskać nazwę klasy poprzez pełnomocnika ... minusem jest to, że metoda musi być na każdym realizacji ...

2

dla Weld na JBoss Application Server to zrobić:

public boolean isProxy(Object obj) { 
    try{ 
     return Class.forName("org.jboss.weld.bean.proxy.ProxyObject").isInstance(obj); 
    } catch (Exception e) { 
     log.error("Unable to check if object is proxy", e); 
    } 
    return false; 
} 

Aby sprowadzaniu rzeczywisty obiekt zamiast pełnomocnictwa (muszę go serializacji) zrobić to:

public Object getObject(Object obj) { 
    Field f = null; 
    boolean isAccessible = false; 
    try { 
     for(Field fi : Class.forName(handler).getDeclaredFields()) { 
      if(fi.getName().equals(field)) { 
       f = fi; 
       isAccessible = f.isAccessible(); 
       f.setAccessible(true); 
      } 
     } 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
    if(f == null) { 
     throw new RuntimeException(new NoSuchFieldException(String.format(
       "The required field '%s' not found in '%s'. " + 
         "May be the code is obsolete for running on this application server.", 
       field, method))); 
    } else { 
     try{ 
      obj = f.get(getHandler(obj)); 
      for(Method m : Class.forName(instance).getMethods()) { 
       if(m.getName().equals(value)) { 
        return m.invoke(obj); 
       } 
      } 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } finally { 
      f.setAccessible(isAccessible); 
     } 
     throw new NoSuchMethodError(String.format(
       "The required method '%s' not found in '%s'. " + 
         "May be the code is obsolete for running on this application server.", 
       value, instance)); 
    } 
} 

Należy pamiętać, że jest to najciemniejsza magia, jak to możliwe, mają bardzo słabą wydajność i może pęknąć w każdej Aktualizacja WildFly, jeśli zmieniają klasy, metody dla pól w nim.