2012-03-19 70 views
12

我想使用google guice在我的應用程序的所有類中提供屬性。我定義了一個模塊,它加載並綁定屬性文件Test.properties使用Google Guice注入java屬性

Property1=TEST 
Property2=25 

package 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. 實例化一個新的注射器狀

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

在所有嵌套類?

  1. 是否有其他方法使所有類中的屬性都可用?
+2

是有你的新理由'他們手動而不是使用guice將它們注入你的測試類(這將是正常的方式)? – Matt 2012-03-19 16:08:03

+0

你的意思是爲什麼「TestConfiguration config = new TestConfiguration();」?你能否舉一個例子來說明如何以另一種方式做到這一點? – markus 2012-03-19 16:13:26

+0

@markus:不,不是'TestConfiguration' ...這對於'new'模塊是正常的。問題是關於'TestImpl'創建其他類,你還需要注入屬性。通常,你會聲明那些其他類(或者它們的提供者)作爲TestImpl的依賴關係,所以Guice可以創建它們,而不是用'TestImpl'中的'new'創建它們。 – ColinD 2012-03-19 16:15:58

回答

11

將噴射器傳遞給所有的子類,然後使用 injector.getInstance(...)創建子類?

不,通過這樣做,您將擊敗dependency injection模式的目的,並且將您的所有實現耦合到Guice。你的實現不應該與guice交互,除非通過(現在是標準化的)註釋。

實例化一個新的注射器狀

TestConfiguration config = new TestConfiguration(); 
Injector injector = Guice.createInjector(config); 
TestImpl test = injector.getInstance(TestImpl.class); 
所有嵌套類

不,這會更糟糕,因爲您最終會得到多個注射器,因此將會阻止正確使用scopes的多個上下文。

理想情況下,您應該只在引導應用程序時使用噴油器。當然,引導它的方式很大程度上取決於應用程序。

是否有其他方法使所有 類中的屬性可用?

這些屬性可以用與TestImpl相同的方式注入。 如果你想讓TestImpl使用同樣需要某些屬性(或其他服務)的服務,只需讓Guice將其注入到TestImpl。 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

「現在我的問題。如果我的TestImpl創建了其他我需要注入屬性的類,並且這些類也需要注入屬性,那麼執行此操作的正確方法是什麼?

經驗法則:避免使用「新」除非絕對必要,否則不要讓您的Impl類「創建其他類」。相反,告訴你的TestImpl,當用guice創建它時,它應該獲得所需的實例注入。

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