2013-02-19 30 views
6

आमतौर पर मैं लकड़हारा इस तरह परिभाषित करते हैं:गूगल Guice का उपयोग कर लकड़हारा इंजेक्षन कैसे

private static final Logger logger = LoggerFactory.getLogger(MyClass.class); 

लेकिन जब @Inject का उपयोग कर हम गैर-स्थिर और गैर अंतिम क्षेत्र का उपयोग करना चाहिए की तरह:

@Inject 
private Logger logger; 

यानी लॉगर इस वर्ग के प्रत्येक उदाहरण में बनाया जाएगा, लॉगर भी परिवर्तनीय है। लॉगर स्थैतिक बनाने के लिए कुछ तरीका मौजूद हो सकता है? साथ ही मैं कुछ वर्ग में लॉगर को कैसे बांध सकता हूं (मैं कारखाने LoggerFactory.getLogger(MyClass.class); से लॉगर ऑब्जेक्ट बनाते समय क्लास ऑब्जेक्ट भेजता हूं, इंजेक्शन का उपयोग करके उसी तरह लॉगर कैसे बना सकता हूं?)?

+2

लॉगर इंजेक्शन के कारण क्या हैं? क्या यह केवल कुछ टाइपिंग से बचने के लिए है? –

उत्तर

7

कृपया Guice विकी पर Custom Injections देखें, एक पूर्ण Log4J उदाहरण है।

संपादित करें: आप अपने लॉगर के लिए static फ़ील्ड या final फ़ील्ड का उपयोग कर सकते हैं, लेकिन static final एक नहीं। यह जावा limitation है।

भी हो सावधान that:

अंतिम क्षेत्रों इंजेक्शन अनुशंसित नहीं है क्योंकि इंजेक्शन मूल्य अन्य थ्रेड को दिखाई नहीं हो सकता है।

कि परीक्षण नहीं किया है लेकिन लेख में कोड स्थिर क्षेत्रों के लिए ठीक काम करना चाहिए, हालांकि आप यह द्वारा MembersInjector से छुटकारा और TypeListener में यह सब करने के (के बाद से एक स्थिर क्षेत्र होने की जरूरत है हो रही है सुधार कर सकते हैं केवल एक बार सेट करें)।

requestStaticInjection() का उपयोग करके आप मॉड्यूल फ़ाइल में अपने सभी वर्गों को सूचीबद्ध करने के लिए मजबूर करेंगे - एक अच्छा विचार नहीं, क्योंकि आप जल्द ही एक को जोड़ना भूल जाएंगे।

ओटीओएच अगर आप सिर्फ JUL का समर्थन करना चाहते हैं तो आप built-in support का उपयोग करने के बेहतर हो सकते हैं (जैसा कि जेफ ने उल्लेख किया है, मुझे लगता है कि आप सामान्य जवाब नहीं चाहते थे, क्योंकि आपने विशेष रूप से अपने प्रश्न में JUL का उल्लेख नहीं किया है)।

+0

मुझे लिंक किए गए आलेख में कई पहलुओं की कमी है: 1) एक नई एनोटेशन की आवश्यकता है।JUL के लिए आप @ इंजेक्ट (दोनों java.inject.Inject और Guice's one) का उपयोग कर सकते हैं। 2) कोई कन्स्ट्रक्टर इंजेक्शन समर्थित नहीं है, 3) कोई विधि इंजेक्शन समर्थित नहीं है 4) सुपरक्लास केवल टिप्पणियों में हैक्स द्वारा समर्थित हैं। सारांश अब तक: JUL समर्थन विशेष है और इसे अन्य लॉगिंग ढांचे में उसी तरीके और गुणवत्ता में स्थानांतरित नहीं किया जा सकता है। –

+0

क्षमा करें, मुझे यह मेरे anwser के लिए संक्रामक या प्रासंगिक नहीं लगता है। 1) नहीं, यह नहीं है कि आप केवल चेक छोड़ सकते हैं और सभी लॉगर फ़ील्ड इंजेक्ट कर सकते हैं 2) हां, लेकिन आप गुइस के साथ काम करने की अपेक्षा कैसे करते हैं? 3) यह समर्थित है, आप जिस भी तरीके से चाहते हैं कक्षा (उदाहरण के लिए देखें) –

+0

मेरा बिंदु, जो आपके उत्तर से प्रासंगिक है, यह है: लिंक किए गए आलेख में इसकी कमी है। प्रस्तावित समाधान इंजेक्शन का समर्थन नहीं करता है उसी तरह गुइस इंजेक्शन का कहीं और समर्थन करता है। ये अंतर स्पष्ट _upfront_ होना चाहिए और तथ्यों के बाद नहीं। विशेष रूप से प्रश्न के अंतिम भाग ("कैसे बनाएं ...") के रूप में और '@ इंजेक्ट' का उपयोग बिल्कुल इस आईएमओ को संबोधित करने लगता है।
मैंने एक ही मामले में तीन मुद्दों का नाम दिया था। यह आपके खिलाफ नहीं है बल्कि केवल उन सभी के लिए है जो उस समाधान का पता लगाना चाहते हैं - अगर वे कहते हैं, "मैं इन चीज़ों के साथ रह सकता हूं।" ठीक है - स्वागत है। –

2

निर्भरता इंजेक्शन के लिए अपने आवेदन को डिजाइन करते समय, आमतौर पर सर्वोत्तम अभ्यास स्थिर क्षेत्रों और विधियों से जितना संभव हो सके से बचने के लिए होता है। ऐसा इसलिए है कि आपकी निर्भरता स्पष्ट है, और इसलिए परीक्षणों के दौरान अन्य वास्तविकताओं के साथ अपनी असली निर्भरताओं को प्रतिस्थापित करना आसान है और आपका आवेदन विकसित होता है। आदर्श व्यवहार, इसलिए, यथासंभव स्थिर विधियों और फ़ील्ड (लॉगर्स समेत) से बचने के लिए है।

गुइस, फ़ील्ड स्थिर, और requesting injection of static fields when the Injector is created चिह्नित करने की अनुमति देता है। खेतों को म्यूटेबल रहने की आवश्यकता होगी - final का मतलब "गुइस को छोड़कर अंतिम" नहीं है।

public class YourClass { 
    @Inject static Logger logger; 

    /* ... */ 
} 

public class YourModule extends AbstractModule { 
    @Override public void configure() { 
    /* YourClass.logger will work once you create your Injector. */ 
    requestStaticInjection(YourClass.class); 
    } 
} 

Guice स्वचालित रूप से इसे में एम्बेड वर्ग के नाम के साथ आप के लिए java.util.logger.Logger instances प्रदान करता है, लेकिन वह केवल a special case coded into Guice के कारण है। यदि आप this SO question में एक विशेष लॉगर चाहते हैं, तो आपको कस्टम इंजेक्शन की जांच करने की आवश्यकता होगी जिसमें जैकब जुड़ा हुआ है - लेकिन यदि पूरा लक्ष्य लॉगर सृजन को केंद्रीकृत करना है, तो आप इसे एक ही स्थान पर नियंत्रित कर सकते हैं, आप केवल उस पर प्रतिक्रिया कर सकते हैं गुइस के बाहर एक स्थिर कारखाने में भी।

@LogToFile 
public class YourClass { 
    private static final Logger logger = YourLoggerFactory.create(YourClass.class); 

    /* ... */ 
} 

public class YourLoggerFactory { 
    private YourLoggerFactory { /* do not instantiate */ } 

    public Logger create(Class<?> clazz) { 
    if (clazz.getAnnotation(LogToFile.class) != null) { 
     return someImplementation(new File(...)); 
    } else { 
     return someOtherImplementation(); 
    } 
    } 
} 
+0

आपके समाधान में कमी है, कि आपके उदाहरण में कक्षा, 'Yourclass.class' का नाम, सभी अनुप्रयोगों में लगातार तरीके से प्रदान किया जाना चाहिए। वह _might_ कारणों में से एक कारण है कि केंद्रीकृत इंजेक्शन को क्यों माना जाता है और सहायक होता है - यह समस्या उचित इंजेक्शन समर्थन के साथ मौजूद नहीं होगी। –

+0

@ एएच। ध्यान दें कि प्रदाता या निर्भरता की इंजेक्शन साइट निर्धारित करने की क्षमता [स्पष्ट रूप से और जानबूझकर एक सुविधा के रूप में खारिज कर दी गई थी] (https://code.google.com/p/google-guice/issues/detail?id=27)। एक उदाहरण फ़ील्ड में, आप 'this' का उपयोग कर सकते हैं, लेकिन एक स्थिर संदर्भ में जावा दुख की बात है कि कक्षा के नाम से ही कोई वाक्यविन्यास छोटा नहीं है। जब आप "उचित इंजेक्शन समर्थन" पाते हैं या बनाते हैं, तो कृपया इसे पास करें - यह देखने में बहुत खुशी होगी कि यह कैसे काम करता है! –

+0

ध्यान दें कि Guice * करता है * अंतिम फ़ील्ड के इंजेक्शन की अनुमति देता है, ऊपर दिए गए मेरे लिंक को एक लिंक के लिए देखें। –