2012-11-24 25 views
5

Proxy'lerle Hibernate kullanıyorum ve test.DBUser$$EnhancerByCGLIB$$40e99a2d gibi sınıflara ait nesneler alıyorum.Proxy sınıfını proxy sınıfından nasıl alabilirim?

Temel sınıfı (test.DBUser bu örnekte) proxy'ye sınıfı sınıfından almak için Hazırda Beklet yöntemi var mı? Ben Hibernate.getClass() hakkında biliyorum, ancak bir Class girdi olarak alırken bir yöntem arıyorum, bir Object alır.

+1

Neden buna ilk olarak ihtiyacınız var? Proxy, temel sınıfınızı genişletir, bu nedenle temel sınıfın bir örneğinde çağırabileceğiniz her yöntem de proxy'de çağrılabilir ve aynı şeyi geri döndürür. –

+0

Bunu, hazırda bekletilen nesnelerin GSON kitaplığına geçirilmesiyle ilgili başka bir soru için araştırıyordum. Kütüphane, uygulayıcıları "Sınıf" vekili ve ancak daha sonra "Nesne" vekili aracılığıyla geçiren bazı çağrılar yapar ve "Sınıf" ile bir şeyler yapmaya başlamak istedim. – Flavio

cevap

3

Bulunduğumdan daha kolay olduğunu öğrendim: daha önce proksiye edilmemiş, orijinal sınıfı elde etmek için proxy sınıfında getSuperclass() numaralı telefonu arayın. Bunun genel olarak ne olduğundan emin değilim, ama işe yarıyor gibi görünüyor.

0

test.DBUser$$EnhancerByCGLIB$$40e99a2d gibi sınıflar dynamic proxies'dur. “Gerçek sınıfın arkasındaki” kavramı çoğu durumda pek anlamlı değildir. Bir vekil her oluşturulduğunda, Hazırda Beklet gibi tanımladığı herhangi bir sınıfın örneği olabilir. soran Sen ne gerçekten

{ Class<Proxy>, Class<RealObject>} arasında Map durağandır. Böyle bir şeye inanmam ya da buna ihtiyaç olduğuna inanıyorum.

339  public static Class getClass(Object proxy) { 
340  if (proxy instanceof HibernateProxy) { 
341   return ((HibernateProxy) proxy).getHibernateLazyInitializer() 
342     .getImplementation() 
343     .getClass(); 
344  } 
345  else { 
346   return proxy.getClass(); 
347  } 
348 } 

Gerçek sınıf almak için statik bir harita arama yapmak çok daha ucuz olurdu ama hazırda uygulama sınıfıyla almak için her yolu tembel başlatıcısı gider: Sadece Hibernate.getClass() kaynağı bak.

0

Böyle bir yöntem yoktur. Sarılmış nesneyi ve dolayısıyla proxy içindeki sınıf bilgilerini almak için kendinize bir yardımcı sınıf yazmanız gerekecektir. Nesneye yalnızca belirtilen senaryoda ihtiyacınız varsa, tüm tembel yüklemeleri kaldırmayı deneyin. Hazırda bekletme, size sade nesneyi vermelidir.

Nesneye gereksinim duymaya çalışmayın. Belki de uygulamayı istediğiniz gibi yeniden tasarlayamazsınız, örneğin çalışma zamanında istenen bilgileri içeren bir alan ekleyerek.

3

Flavio tarafından yayınlanan yaklaşımın sadeliğini gerçekten beğendiğim halde, desteklendiği şekilde belgelenmediği sürece bunu üretim kodunda kullanamıyorum. Ayrıca, eğer LazyInitializer üzerinde .getImplementation() öğesini çağırırsanız, zaten değilse, proxy'nin başlatılmasını zorlar, bu da olumsuz bir performans etkisidir. Bu sorunların her ikisini de ele alan bu yaklaşımla geldim:

public static Class<?> getClassForHibernateObject(Object object) { 
    if (object instanceof HibernateProxy) { 
    LazyInitializer lazyInitializer = 
     ((HibernateProxy) object).getHibernateLazyInitializer(); 
    return lazyInitializer.getPersistentClass(); 
    } else { 
    return object.getClass(); 
    } 
}