2010-07-17 16 views
7

एक समृद्ध डोमेन संचालित डिज़ाइन के लिए मैं जेपीए/हाइबरनेट इकाई बीन्स पर गुइस निर्भरता इंजेक्शन का उपयोग करना चाहता हूं। मैं गैर-स्प्रिंग बीन्स के लिए स्प्रिंग @ कॉन्फिगर करने योग्य एनोटेशन के समान समाधान ढूंढ रहा हूं।इकाई सेम के लिए गुइस निर्भरता इंजेक्शन?

क्या कोई पुस्तकालय के बारे में जानता है? कोई कोड उदाहरण?

उत्तर

5

आप इसे AspectJ के साथ कर सकते हैं।

@Configurable टिप्पणी बनाएं:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.TYPE}) 
public @interface Configurable { 
} 

एक AspectJ @Aspect इस के समान बनाएं: (और उपयोग) अपने इंजेक्टर के लिए

@Aspect 
public class ConfigurableInjectionAspect { 
    private Logger log = Logger.getLogger(getClass().getName()); 

    @Pointcut("@within(Configurable) && execution(*.new(..)) && target(instantiated)") 
    public void classToBeInjectedOnInstantiation(Object instantiated) {} 

    @After(value = "classToBeInjectedOnInstantiation(instantiated)", 
      argNames = "instantiated") 
    public void onInstantiation(Object instantiated) { 
     Injector injector = InjectorHolder.getInjector(); 
     if (injector == null) { 
      log.log(Level.WARNING, "Injector not available at this time"); 
     } else { 
      injector.injectMembers(instantiated); 
     } 
    } 
} 

बनाएँ होल्डिंग वर्ग:

public final class InjectorHolder { 

    private static Injector injector; 

    static void setInjector(Injector injector) { 
     InjectorHolder.injector = injector; 
    } 

    public static Injector getInjector() { 
     return injector; 
    } 
} 

मेटा-आईएनएफ/एओपी.एक्सएमएल कॉन्फ़िगर करें:

<aspectj> 
    <weaver options="-verbose"> 
     <include within="baz.domain..*"/> 
     <include within="foo.bar.*"/> 
    </weaver> 
    <aspects> 
     <aspect name="foo.bar.ConfigurableInjectionAspect"/> 
    </aspects> 
</aspectj> 
aspectjweaver के साथ अपने वीएम शुरू

:

-javaagent:lib/aspectjweaver.jar 

एन्नोटेट आपके डोमेन कक्षाएं:

@Entity 
@Table(name = "Users") 
@Configurable 
public class User { 
    private String username; 
    private String nickname; 
    private String emailAddress; 
    @Inject 
    private transient UserRepository userRepository 

    public User() {} 
} 
1

चूंकि संस्थाएं जेपीए प्रदाता द्वारा बनाई गई हैं, इसलिए मैं यह देखने में असफल रहा कि गुइस कब खेलेंगे। हो सकता है कि Salve प्रोजेक्ट के दृष्टिकोण पर नज़र डालें।

+0

धन्यवाद, साल्वे की तरह एक codeweaving समाधान वास्तव में चाल कर सकता है। मैंने साल्व की कोशिश की, लेकिन इसमें सीमित दस्तावेज है और मैं इसे कुछ भी नहीं कर सकता (यहां तक ​​कि एक त्रुटि संदेश भी नहीं)। बस कुछ सरल नमूना कोड की उम्मीद है, उदाहरण के लिए AspectJ या इससे भी बेहतर एओपी। – Kdeveloper

+0

@Kdeveloper: मुझे साल्व के साथ कोई अनुभव नहीं है, इसलिए मैं इसकी अनुशंसा नहीं कर सकता लेकिन यह आपको कुछ ऐसा लागू करने के लिए कुछ विचार दे सकता है, इसलिए मैंने इसका उल्लेख किया है –

3

मैं इस समस्या के लिए एक सा गंदा वैकल्पिक हल मिल गया।

मान लिया जाये कि वहाँ प्रकार T की एक इकाई वस्तु बनाने के लिए केवल दो तरीके हैं:

  • एक javax.inject.Provider<T>
  • से एक प्राप्त इकाई प्रबंधक (जो @PostLoad एनोटेट तरीकों कॉल करेंगे) से यह quering।

आगे यह मानते हुए कि आपके पास अपनी सभी इकाइयों के लिए आधारभूत आधार है, आप इस इकाई में केवल एक इकाई श्रोता जोड़ सकते हैं। इस उदाहरण में मैं स्थैतिक इंजेक्शन का उपयोग करता हूं - शायद एक अच्छा तरीका है।

@MappedSuperclass 
public abstract class PersistentDomainObject<K extends Serializable & Comparable<K>> 
    implements Comparable<PersistentDomainObject<K>>, Serializable { 

    private static transient Injector injector; 

    @PostLoad 
    private final void onAfterLoaded() { 
     injector.injectMembers(this); 
    } 

    @EmbeddedId 
    private K id; 

    public K getId() { return id; } 

    // ... compareTo(), equals(), hashCode(), maybe a @Version member ... 
} 

अपने मॉड्यूल सेटअप में तुम सिर्फ requestStaticInjection(PersistentDomainObject.class);

अब कॉल करने के लिए आप बस

@Entity 
public class MyDomainEntity extends PersistentDomainObject<SomeEmbeddableIdType> 
    implements HatLegacyId { 

    @Inject 
    private transient MyDomainService myDomainService; 

    private String name; 
    // ... common stuff 
} 

इसके बारे में बुरी बात की तरह इकाई कक्षाएं बना सकता है की जरूरत है, तो आप कि कोई भी भरोसा करने के लिए पैदा करेगा है एक MyDomainEntity अपने आप पर है लेकिन इसके लिए Provider<MyDomainEntity> पूछेगा। यह कन्स्ट्रक्टर छुपाकर प्रदान किया जा सकता है।

सधन्यवाद,

avi

+0

भले ही स्थिर इंजेक्शन किसी तरह से निराश हो, निर्भरता जोड़ना इस समय AspectJ की तरह मेरी परियोजना के लिए सस्ती नहीं है। इसके अलावा, समाधान मेरी समस्या के लिए उपयुक्त है और काफी साफ है। – Iacopo

संबंधित मुद्दे