使用Provider來例項化/注入第三方物件

梧桐雨—168發表於2008-03-19
能有一個用Guice來例項化/注入一個DataSource,或者第三方物件的例子麼?
比如在Spring的環境下可以如下配置:
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        ...
        2
        sa
       
        ...
Dhanji R.Prasanna————
你可以建立一個Provider來滿足這個需求並且配置其中的值:
public class BDSProvider implements Provider {
     @Inject @Named("ds.initial_size") int initialSize;
     @Inject @Named("ds.username") String username;
     //..
     public BasicDataSource get() {
          BasicDataSource source = new BasicDataSource();
          source.setInitialSize(initialSize);
          source.setUsername(username);
          //...etc.
          return source;
     }
}
然後把該provider繫結:
bind(BasicDataSource.class).toProvider(BDSProvider.class);
接著可以從某個配置檔案(properties)中配置
bindProperties()....
jfz————
下面是一個能工作的程式碼,他有什麼設計問題?
protected void configure() {
        ...
        final BasicDataSource bds = new BasicDataSource();
        bds.setUrl("url");bds.setUsername("uName");...
        bind(BasicDataSource.class).toInstance(bds);
       ...
}

Dhanji R.Prasanna————
雖然他能工作,但意味著:
1,BDS現在是一個singleton的了
2,BDS是迫切的初始化(eagerly instantiated)
3,你將模組的繫結和工廠程式碼混淆在一起了
4,你將url,username等應該放在一個非java檔案的東西用於例項化了。
 
討論到這裡,並沒有給一個全面的使用Provider的示例,
下面給出一個我使用Provider的測試:
首先模擬一個DataSource:
package com.easyjf.guicUse.third;
public class MockDataBase {
 private String userName;
 private String password;
 private int initialNum;
 public int getInitialNum() {
  return initialNum;
 }
 public void setInitialNum(int initialNum) {
  this.initialNum = initialNum;
 }
 public String getPassword() {
  return password;
 }
 public void setPassword(String password) {
  this.password = password;
 }
 public String getUserName() {
  return userName;
 }
 public void setUserName(String userName) {
  this.userName = userName;
 }
 
 public String connect(){
  return this.initialNum+this.userName+this.password;
 }
}
然後建立一個Porvider來代理
package com.easyjf.guicUse.third;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
public class BDSProvider implements Provider{
 @Inject
 @Named("ds.initial_size")
 int initialSize;
 @Inject
 @Named("ds.userName")
 String userName;
 @Inject
 @Named("ds.password")
 String password;
 public MockDataBase get(){
  MockDataBase source=new MockDataBase();
  source.setInitialNum(this.initialSize);
  source.setUserName(userName);
  source.setPassword(password);
  return source;
 }
}
接著建立一個mockDao來使用該DataSource:
package com.easyjf.guicUse.third;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class MockDao {
 private MockDataBase dataSource;
 
 @Inject
 public MockDao(Provider provider){
  dataSource = provider.get();
 }
 
 public String go(){
  return dataSource.connect();
 }
}
然後是一個Module來繫結該Provider:
package com.easyjf.guicUse.third;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
import com.google.inject.AbstractModule;
import com.google.inject.name.NamedImpl;
public class MyModule extends AbstractModule {
 private int num;
 private String userName;
 private String password;
 public MyModule() throws Exception{
  Properties properties=new Properties();
  File file=new File("config.properties");
  properties.load(new FileInputStream(file));
  this.num=Integer.parseInt(properties.getProperty("ds.initial_size"));
  this.userName=properties.getProperty("ds.userName");
  this.password=properties.getProperty("ds.password");
 }
 @Override
 protected void configure() {
  // TODO Auto-generated method stub
  bind(MockDataBase.class).toProvider(BDSProvider.class);
  this.bind(int.class).annotatedWith(Names.named("ds.initial_size")).toInstance(num);
  this.bind(String.class).annotatedWith(Names.named("ds.userName")).toInstance(userName);
  this.bind(String.class).annotatedWith(Names.named("ds.password")).toInstance(password);
 }
}
這裡把引數放在了一個config.properties檔案裡面
下面是測試:
package com.easyjf.guicUse.third;
import junit.framework.TestCase;
import com.google.inject.Guice;
import com.google.inject.Injector;
public class DaoTest extends TestCase {
 public void testGo() throws Exception{
  Injector injector=Guice.createInjector(new MyModule());
  MockDao dao=new MockDao(injector.getProvider(MockDataBase.class));
  assertEquals("1stefpassword",dao.go());
 }
}
OK,第一個關於Guice的文章完成~

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/13270562/viewspace-211685/,如需轉載,請註明出處,否則將追究法律責任。

相關文章