2014-08-29 6 views
5

In CDI 1.2 esiste un modo per verificare se un'istanza di classe è proxificata? Ho bisogno di questo perché ho bisogno di ottenere il nome della classe originale, non il nome del proxy.Controllare se la classe è sottoposta a proxy con 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 
} 

Uso delle classi di saldatura che posso fare questo lavoro:

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 non esiste un metodo per fare questo. Cerco all'interno dei documenti CDI 1.2 se è stato aggiunto un metodo a riguardo, ma non ho trovato nulla.

Quindi ... Mi manca qualcosa e CDI 1.2 c'è un metodo per ottenere il nome della classe e l'istanza originali? O se no, c'è un piano per aggiungere questa funzionalità in quasi caratteristica?

+1

Qual è il caso d'uso per scoprire la classe del fagiolo? Considerando che stai iniettando 'Bean Bean', sai già che implementa' Bean' –

+0

Hai provato questa soluzione? http://stackoverflow.com/a/7504552/2492784 – Sven

risposta

0

Questo è un attacco terribile, ma per Weld (e forse altre implementazioni) è possibile controllare se il nome della classe contiene "Proxy": possibleProxy.getClass().getSimpleName().contains("Proxy"). Io lo uso solo per scopi di registrazione per ottenere una versione ripulita del nome della classe avvolto:

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

si può fare un metodo all'interno il bean cdi proxy come

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

questa non è la soluzione migliore , ma un semplice modo pragmatico per ottenere il nome di classe attraverso il proxy ... il rovescio della medaglia è che il metodo deve essere in ogni applicazione ...

2

per saldare wildfly fare questo:

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

Per retrive effettivo oggetto invece di delega (ho bisogno di serializzare esso) faccio questo:

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

Essere consapevoli, che è la magia più scuro possibile, hanno prestazioni molto povera e può rompere in qualsiasi Aggiornamento WildFly, se cambiano classi, metodi per i campi in esso contenuti.

Problemi correlati