Propertiesの内容をInjectする
Propertiesの内容をInjectしてインスタンスを生成するファクトリです。
Injectorは、On-Demandとして利用します。
public class GuiceInstanceFactory { public static <T>T getInstance(Class<T> cls, final Properties properties) { Injector injector = Guice.createInjector(new AbstractModule() { @Override protected void configure() { Names.bindProperties(binder(), properties); } }); return injector.getInstance(cls); } public static <T> T getInstance(Class<T> cls, final Map<String, String> properties) { Injector injector = Guice.createInjector(new AbstractModule(){ @Override protected void configure() { Names.bindProperties(binder(), properties); } }); return injector.getInstance(cls); } }
んでこちらが、Injectに名前付けしたクラスです。
ポイントはoptionalをつけておき、On-demandの外部からのInject時にnull代入でエラーとならないようにしておきます。。
public class XADataSourcePaeImpl implements XADataSource { private Logger logger = Logger.getLogger(XADataSourcePaeImpl.class); @Inject(optional = true) @Named("driverClassName") private String driverClassName; @Inject(optional = true) @Named("url") private String url; @Inject(optional = true) @Named("user") private String user; @Inject(optional = true) @Named("password") private String password; private Properties properties = new Properties(); @Inject(optional = true) @Named("loginTimeout") private int loginTimeout;
そして、上位のInjectorに通知するためのModuleです。
ここでは、単純に指定のプロパティファイルから読み込んでInstance取得後
bindしてあげています。
public class XADataSourceModule extends AbstractModule{ @Override protected void configure() { Properties properties = new Properties(); try { properties.load(XADataSource.class.getResourceAsStream("/xadatasource.properties")); } catch (IOException e) { throw new RuntimeException(e.getMessage(),e); } XADataSourcePaeImpl instance = GuiceInstanceFactory.getInstance(XADataSourcePaeImpl.class, properties); bind(XADataSource.class).toInstance(instance); } }
一応、プロパティファイルも・・
driverClassName=A url=jdbc user=ellectra password=password loginTimeout=10
プロパティをファイルからの取得ではなくデータベースからの取得にしたり、どのプロパティファイルから読み込むのかネーミングルールが定義できたりすると良いので、それは次のステップで解決するに申し送り。