2014-08-29 11 views
5

In CDI 1.2 gibt es eine Möglichkeit, zu überprüfen, ob eine Klasseninstanz gekürzt wird? Ich brauche das, weil ich den Namen der ursprünglichen Klasse, nicht den Proxy-Namen erhalten muss.Überprüfen, ob Klasse mit CDI 1.2 spezifiziert ist

@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 
} 

Weld Klassen ich diesen Job tun kann:

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()); 
} 

In CDI 1.1 gibt es keine Methode, dies zu tun. Ich suche in CDI 1.2 Dokumente, wenn eine Methode dazu hinzugefügt wurde, aber ich habe nichts gefunden.

Also ... ich vermisse etwas und CDI 1.2 gibt es eine Methode, um ursprünglichen Klassennamen und Instanz zu bekommen? Oder wenn nicht, gibt es eine Ebene, um diese Funktion in Near Feature hinzuzufügen?

+1

Was ist der Anwendungsfall zum Ermitteln der Klasse der Bohne? Wenn man bedenkt, dass man 'Bohne 'injiziert, weiß man bereits, dass es' Bean' implementiert. –

+0

Haben Sie diese Lösung ausprobiert? http://stackoverflow.com/a/7504552/2492784 – Sven

Antwort

0

Dies ist ein schrecklicher Hack, aber für Weld (und möglicherweise andere Implementierungen) können Sie überprüfen, ob der Klassenname "Proxy" enthält: possibleProxy.getClass().getSimpleName().contains("Proxy"). Ich benutze es nur zur Protokollierung eine aufgeräumt Version des umwickelten Klassennamen zu erhalten:

/** 
* 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

Sie eine Methode in Ihrer proxied cdi Bohne machen kann wie

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

dies ist nicht die beste Lösung , sondern eine einfache pragmatische Art und Weise die Klassennamen durch den Proxy ... die Kehrseite der Medaille zu bekommen, ist, dass das Verfahren bei jeder Implementierung sein muss ...

2

Für Weld auf Wildfly dies tun:

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; 
} 

Um eigentliches Objekt statt Proxy retrive (ich es serialisiert werden muß) Ich tue dies:

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)); 
    } 
} 

bewusst sein, dass es die dunkelste Magie wie möglich ist, haben eine sehr schlechte Leistung und brechen kann auf jedem WildFly aktualisiert, wenn sie Klassen ändern, Methoden für Felder darin.