2012-03-19 4 views
12

मैं अपने आवेदन के सभी वर्गों में गुणों को उपलब्ध कराने के लिए Google guice का उपयोग करना चाहता हूं। मैंने एक मॉड्यूल परिभाषित किया जो गुण फ़ाइल Test.properties लोड करता है और बांधता है।जावा गुणों को इंजेक्ट करने के लिए Google Guice का उपयोग

Property1=TEST 
Property2=25 

पैकेज com.test;

import java.io.FileNotFoundException; 
import java.io.FileReader; 
import java.io.IOException; 
import java.util.Properties; 

import com.google.inject.AbstractModule; 
import com.google.inject.name.Names; 

public class TestConfiguration extends AbstractModule { 

    @Override 
    protected void configure() { 
    Properties properties = new Properties(); 
    try { 
     properties.load(new FileReader("Test.properties")); 
     Names.bindProperties(binder(), properties); 
    } catch (FileNotFoundException e) { 
     System.out.println("The configuration file Test.properties can not be found"); 
    } catch (IOException e) { 
     System.out.println("I/O Exception during loading configuration"); 
    } 

    } 
} 

मैं एक मुख्य वर्ग का उपयोग कर रहा हूं जहां मैं गुणों को इंजेक्ट करने के लिए इंजेक्टर बनाता हूं।

package com.test; 

import com.google.inject.Guice; 
import com.google.inject.Injector; 

public class Test { 

    public static void main(String[] args) { 
    TestConfiguration config = new TestConfiguration(); 
    Injector injector = Guice.createInjector(config); 
    TestImpl test = injector.getInstance(TestImpl.class); 
    } 
} 

package com.test; 

import com.google.inject.Inject; 
import com.google.inject.name.Named; 

public class TestImpl { 
    private final String property1; 
    private final Integer property2; 

     @Inject 
     public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2) { 

     System.out.println("Hello World"); 
     this.property1 = property1; 
     this.property2 = property2; 

     System.out.println(property1); 
     System.out.println(property2); 

     } 
    } 

अब मेरा प्रश्न। यदि मेरा testImpl अन्य वर्ग बनाता है जहां मुझे गुणों को इंजेक्ट करने की भी आवश्यकता होती है, और उन वर्गों को गुणों को इंजेक्ट करने की भी आवश्यकता होती है तो ऐसा करने का सही तरीका क्या है?

  1. सभी उपवर्गों इंजेक्टर दर्रा और फिर injector.getInstance (...) का उपयोग उपवर्गों बनाने के लिए?

  2. Instanciate

    TestConfiguration config = new TestConfiguration(); 
    Injector injector = Guice.createInjector(config); 
    TestImpl test = injector.getInstance(TestImpl.class); 
    

सभी नेस्टेड कक्षाओं में की तरह एक नया इंजेक्टर?

  1. वहाँ एक अन्य दृष्टिकोण गुण सभी वर्गों में उपलब्ध बनाने के लिए है?
+2

स्थापित करना होगा वहाँ एक कारण है कि आप नए हैं, उन्हें अपने टेस्ट क्लास में इंजेक्ट करने के लिए गुइस का उपयोग करने के विरोध में मैन्युअल रूप से उन्हें डालना (जो सामान्य तरीका होगा)? – Matt

+0

आपका मतलब है कि "टेस्ट कॉन्फ़िगरेशन कॉन्फ़िगरेशन = नया टेस्ट कॉन्फ़िगरेशन();"? क्या आप एक उदाहरण दे सकते हैं कि इसे किसी अन्य तरीके से कैसे किया जाए? – markus

+0

@ मार्कस: नहीं, 'टेस्ट कॉन्फ़िगरेशन' नहीं ... यह 'नए' मॉड्यूल के लिए सामान्य है। सवाल 'टेस्टआईएमपीएल' के बारे में है जो अन्य वर्गों को बनाते हैं जहां आपको गुणों को इंजेक्ट करने की भी आवश्यकता होती है। आम तौर पर, आप उन अन्य वर्गों (या 'प्रदाता' की घोषणा 'टेस्टआईएमपीएल' की निर्भरताओं के रूप में घोषित करेंगे ताकि गिस उन्हें 'TestImpl' में 'नए' के ​​साथ बनाने के बजाय उन्हें बना सके। – ColinD

उत्तर

11

सभी उप-वर्गों के इंजेक्टर को पास करें और फिर उप-वर्ग बनाने के लिए इंजेक्टर.getInstance (...) का उपयोग करें?

नहीं, ऐसा करके आप dependency injection पैटर्न के उद्देश्य को हरा रहे हैं और आपके सभी कार्यान्वयन को गुइस में जोड़ रहे हैं। आपके कार्यान्वयन को (अब मानकीकृत) एनोटेशन के अलावा, गुइस के साथ बिल्कुल बातचीत नहीं करनी चाहिए।

Instanciate तरह

TestConfiguration config = new TestConfiguration(); 
Injector injector = Guice.createInjector(config); 
TestImpl test = injector.getInstance(TestImpl.class); 
सभी नेस्टेड कक्षाओं में

एक नया इंजेक्टर?

नहीं, और यह भी बदतर कारण है कि आप एकाधिक इंजेक्टरों के साथ समाप्त हो जाएंगे, इसलिए कई संदर्भ जो scopes के उचित उपयोग को रोक देंगे।

आदर्श रूप में, आपको केवल अपने आवेदन के बूटस्ट्रैपिंग के दौरान इंजेक्टर का उपयोग करना चाहिए। बेशक बूटस्ट्रैप करने का तरीका यह काफी हद तक आवेदन पर निर्भर करेगा।

क्या कक्षाओं में गुणों को उपलब्ध कराने के लिए कोई अन्य दृष्टिकोण है?

गुणों को इंजेक्शन दिया जा सकता है जैसा आपने TestImpl के लिए किया था। यदि आप टेस्टआईएमपीएल का उपयोग करना चाहते हैं तो एक ऐसी सेवा कहें जो कुछ गुणों (या अन्य सेवाओं) की भी आवश्यकता है, बस गिस को टेस्टआईएमपीएल में इंजेक्ट करने दें। गुइस सभी तत्काल/तारों का ख्याल रख रहा है। आप केवल Guice "कैसे आगे बढ़ना है",, बांधने की मशीन का उपयोग करके बताना चाहिए जब Guice यह पता ही समझ नहीं सकता:

public class TestImpl { 
    private final String property1; 
    private final Integer property2; 
    private final IService service; 


     @Inject 
     public TestImpl(@Named("Property1") String property1, @Named("Property2") Integer property2, IService service) { 
      this.property1 = property1; 
      this.property2 = property2; 
      this.service= service; 
     } 
    } 
} 
0

"अब मेरा प्रश्न। यदि मेरा टेस्टआईम्प्ल अन्य वर्ग बनाता है जहां मुझे गुणों को इंजेक्ट करने की भी आवश्यकता होती है, और उन वर्गों को गुणों को इंजेक्ट करने की भी आवश्यकता होती है तो ऐसा करने का सही तरीका क्या है?"

अंगूठे का नियम: "नया" के उपयोग से बचें जब तक कि यह बिल्कुल जरूरी नहीं है, अपने इंपल क्लास को "अन्य कक्षाएं" न दें। इसके बजाय, अपने टेस्टआईएमपी को बताएं कि जब गुइस के साथ बनाया गया है, तो उसे आवश्यक उदाहरण इंजेक्शन मिलना चाहिए।

2

लाइब्रेरी "Governator" guice इंजेक्शन के लिए एक विन्यास मानचित्रण सुविधा प्रदान करते हैं। दृष्टिकोण अलग है, लेकिन गुण फ़ाइलों से लोड उपलब्ध है।

https://github.com/Netflix/governator/wiki/Configuration-Mapping

1

पुस्तकालय Guice configuration आप अपनी सेवाओं के लिए गुण या JSON फाइलों से मूल्यों के लिए इंजेक्षन कर सकते हैं।

आप application.properties आपकी सेवा के लिए के रूप में फ़ाइल से इंजेक्षन कर सकते हैं:

@BindConfig(value = "application", syntax = PROPERTIES) 
public class Service { 

    @InjectConfig 
    private int port; 

    @InjectConfig 
    private String url; 

    @InjectConfig 
    private Optional<Integer> timeout; 
} 

आप बस मॉड्यूल ConfigurationModule

public class GuiceModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     install(ConfigurationModule.create()); 
     requestInjection(Service.class); 
    } 
}