2014-08-29 44 views
5

proxified在CDI 1.2還有一個方法來檢查,如果一個類實例proxified?我需要這個,因爲我需要獲取原始類的名稱,而不是代理名稱。檢查是否類與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 
} 

使用焊接類我可以做這個工作:

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

在CDI 1.1沒有方法做到這一點。我搜索裏面CDI 1.2文檔,如果加入這個方法,但我沒有發現任何東西。

所以......我想念的東西,CDI 1.2還有就是讓原來的類名和實例的方法?或者,如果沒有,有一個普通的功能添加此功能?

+1

有什麼用例找出bean的類?考慮到你注入'豆bean'你已經知道,它實現了'Bean' – 2014-08-30 19:26:13

+0

你有沒有試過這種解決方案? http://stackoverflow.com/a/7504552/2492784 – Sven 2014-09-09 19:38:54

回答

0

這是一個可怕的黑客,但焊接(可能還有其他的實現),您可以檢查類名稱中包含「代理」:possibleProxy.getClass().getSimpleName().contains("Proxy")。我只使用它進行日誌記錄,以獲得包裹類名稱的清理版本:

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

,你可以讓你的代理CDI bean中的方法類似

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

這是不是最好的解決辦法,但一個簡單實用的方式通過代理獲取類名字......這樣做的缺點是,該方法必須對每個執行...

2

焊縫上WildFly做到這一點:

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

以檢索實際的對象,而不是代理(我需要序列化)我這樣做:

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

要知道,這是最黑暗的魔法成爲可能,具有非常差的性能,可以在任何突破WildFly更新,如果他們改變類,它的字段方法。