2016-05-03 10 views
1

私はJavaプロジェクトを持っており、Guiceを実装する必要があります。Guiceデータベース工場

私はモジュラープロジェクトを持っているので、データベースを簡単に切り替えることができます。工場出荷時は次のようにMySQLの探し接続返す

public abstract class DBConnectionFactory { 
    // List of DAO types supported by the factory 
    public static final int MYSQL = 1; 
    public static final int ORACLE = 2; 

    public abstract FilterDAO getFilterDAO(); 
    public abstract PhotoDAO getPhotoDAO(); 
    public abstract SetDAO getSetDAO(); 

    public static DBConnectionFactory getDBConnectionFactory(int whichFactory) { 
     switch (whichFactory) { 
      case MYSQL: 
       return new MySQLFactory(); 
      case ORACLE: 
       return new OracleFactory(); 
      default: 
       return null; 
     } 
    } 
} 

::私はこのようになります工場のDBConnection持っていることを行うには私のServletControllerで

public class MySQLFactory extends DBConnectionFactory { 
    public static final String DRIVER= "com.mysql.jdbc.Driver"; 
    public static final String DBURL= "jdbcurl"; 
    private static final String PASSWORD = "password"; 
    private static final String USERNAME = "username"; 

    // method to create MySQL connection 
    public static Connection createConnection() { 
     try { 
      // This will load the MySQL driver, each DB has its own driver 
      Class.forName(DRIVER); 
      Connection connect = DriverManager.getConnection(DBURL, USERNAME, PASSWORD); 
      return connect; 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
    public FilterDAO getFilterDAO() { return new MySQLFilterDAO(); } 
    public PhotoDAO getPhotoDAO() { 
     return new MySQLPhotoDAO(); 
    } 
    public SetDAO getSetDAO() { 
     return new MySQLSetDAO(); 
    } 
} 

を私は接続を確立するには、このコードを持っています:

// Create a DAO 
private DBConnectionFactory MySQLFactory = DBConnectionFactory.getDBConnectionFactory(DBConnectionFactory.MYSQL); 

@Override 
public void init(){ 
    photoDAO = MySQLFactory.getPhotoDAO(); 
} 

私は工場を取り除き、Guiceを使用しようとしていますが、どこから始めるべきかわかりません。前もって感謝します!

+0

基本的な前提は、あなたはもう、これらすべての工場を必要としないということです。 '(PhotoDAOInterface.class).to(PhotoDAOImpl.class)'をバインドし、他のクラスのコンストラクタに '@Inject'することができます。それぞれの 'PhotoDAOImpl'はコンストラクタに注入された設定値を持つことができ、クラスを別々に簡単にテストすることができます。ファクトリーは簡単にテストされません。したがって、基本的な例を提供するには: '@Inject public ServletController(PhotoDAO photoDAO){this.photoDAO = photoDAO; } 'テストのために、'(PhotoDAOInterface.class).to(PhotoDAOTestingImpl.class) 'をバインドすることができ、何も変わりません! – AmazingDreams

+0

ありがとう!しかし、今私はどのデータベースを使用するかを定義するのですか? (MySQLまたはOracle?) – Robert

+0

'MySQLConnection'と' OracleConnection'の両方が同じインターフェースを使用すると仮定します。 guiceを使って 'FlagDAO'のコンストラクタへの別の種類の接続を' @Inject 'します。より理解しやすい説明のために私の答えを見てください。 – AmazingDreams

答えて

0

私のコメントを拡大し、より良い例を提供します。これは、プレイフレームワークを前提としていますが、原理は全く同じでなければなりません。

Guiceを使用する際にまず必要とするのは、インターフェイスへの実装のバインドです。たとえば、私はFlagDAOが必要です。

// This one is used in production/development 
public class FlagDAOEbean implements FlagDAO { 
    // Some code 
} 

// This one is used for testing 
public class FlagDAOInMemory implements FlagDAO { { 
    // Some code 
} 

をいくつかの他のサービスでFlagDAOを使用するには:

public interface FlagDAO { 
    public Flag getByName(String name) throws FlagNotFoundException; 
} 

は今、私は完全にコードが表示されませんそのうち、それの実装のカップルを持っています。適切な値は、フレームワークを今すぐプレイ

public class SomethingUsingFlagDAO { 
    @Inject 
    public SomethingUsingFlagDAO(FlagDAO flagDAO) { 
    } 
} 

を注入されたアプリケーションの起動時に特定のものをバインドするためにモジュールを使用しているように、この SomethingUsingFlagDAOクラスは、Guiceのを通じて構築されなければなりません。テストでこのモジュールを無効にしましたが、コードは開発環境と運用環境で実行されます。

public class DAOModule extends AbstractModule { 
    public void configure() { 
     bind(FlagDAO.class).to(FlagDAOEbean.class); 
     bind(SomethingUsingFlagDAOInterface.class).to(SomethingUsingFlagDAO.class); 
    } 
} 

私のテストケースにはこのコードがあります。実際に異なっている唯一のことは、FlagDAO実装はGuiceのにバインドされていることに注意してください:

public class FlagsTest extends WithApplication { 

    private SomethingUsingFlagDAO something; 

    @Before 
    public void setUp() { 
     Injector injector = this.provideApplication().injector(); 
     this.something = injector.instanceOf(SomethingUsingFlagDAO.class); 
    } 

    @Override 
    protected Application provideApplication() { 
     Application application = new GuiceApplicationBuilder() 
       .in(new Environment(new File("./"), this.getClass().getClassLoader(), Mode.TEST)) 
       .bindings(bind(FlagDAO.class).to(FlagDAOInMemory.class)) 
       .bindings(bind(SomethingUsingFlagDAOInterface.class).to(SomethingUsingFlagDAO.class)) 
       .build(); 

     return application; 
    } 
} 

だから我々は、開発/生産/テスト環境であるかどうかに応じて異なるDAOの実装は、実際にどのように、何も変更せずに使用されています働くいいえif (application.isTesting())は、どこにしてはならないかをチェックします。

あなたがそうのようにバインドされ FlagDOAEbeanFlagDAOInMemoryと一緒 FlagDAOOracleを想像することができ、あなたの場合は

:Guiceのの

public class DAOModule extends AbstractModule { 
    public void configure() { 
     if(weNeedOracle) { 
      bind(FlagDAO.class).to(FlagDAOOracle.class); 
     } else { 
      bind(FlagDAO.class).to(FlagDAOMysql.class); 
     } 
    } 
} 
+0

ありがとうございます!非常に明確な説明。しかし私はコントローラを持っていないサーブレットコントローラを持っているが、注入が必要な問題に直面しています。回避策はありますか? – Robert

+0

コンストラクタを使用できないということですか?私はあなたがこれを試すことができると思う:https://github.com/google/guice/wiki/Servlets – AmazingDreams

+0

私はまだサーブレットにどのように注入することができません。私は思いつくことができるすべてのオプションを試しました。コントローラ付きサーブレットの実装方法御時間ありがとうございます – Robert