Google Guice is a dependency injection framework used to wire application.
Maven
To start using Google Guice with Maven, add the following dependency to your POM.<dependency> <groupid>com.google.inject</groupid> <artifactid>guice</artifactid> <version>4.0</version> </dependency>
Guice Module
Next, subclass an AbstractModule with your dependencies. For example, this file configures some constants, a pair of DAOs, and some JavaFX objects.package com.bekwam.examples.javafx.oldscores1; import com.google.inject.AbstractModule; import com.google.inject.name.Names; import javafx.fxml.JavaFXBuilderFactory; import javafx.util.BuilderFactory; public class OldScoresModule extends AbstractModule { final private static String MATH_RECENTERED_JSON_FILE = "/data/mathRecentered.json"; final private static String VERBAL_RECENTERED_JSON_FILE = "/data/verbalRecentered.json"; final private static String SETTINGS_FILE_NAME = ".oldscores"; @Override protected void configure() { String mathRecenteredJSONFile = MATH_RECENTERED_JSON_FILE; String verbalRecenteredJSONFile = VERBAL_RECENTERED_JSON_FILE; String settingsFileName = SETTINGS_FILE_NAME; bind(BuilderFactory.class).to(JavaFXBuilderFactory.class); bind(String.class).annotatedWith(Names.named("mathRecenteredJSONFile")).toInstance(mathRecenteredJSONFile); bind(String.class).annotatedWith(Names.named("verbalRecenteredJSONFile")).toInstance(verbalRecenteredJSONFile); bind(String.class).annotatedWith(Names.named("settingsFileName")).toInstance(settingsFileName); bind(SettingsDAO.class).to(SettingsDAOImpl.class).asEagerSingleton(); bind(RecenteredDAO.class).to(RecenteredDAOImpl.class).asEagerSingleton(); } }
Initialize Guice
To start the dependency injection, create a Guice Injector in your main entry point. This example is a JavaFX application that creates an Injector.@Override public void start(Stage primaryStage) throws Exception { if( logger.isDebugEnabled() ) { logger.debug("[START]"); } Injector injector = Guice.createInjector(new OldScoresModule()); // continue with start() }
Apply to Objects - Direct Call
Your Injector provides you with a factory to create Guice-enabled objects. This example uses Guice to return a JavaFX BuilderFactory configured in OldScoresModule to return a JavaFXBuilderFactory object. GuiceControlFactory is a class that doesn't require an explicit binding. Guice understands the to get() a GuiceControlFactory means to return an object of that class.FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml1/MainView.fxml"), null, injector.getInstance(BuilderFactory.class), injector.getInstance(GuiceControllerFactory.class));
Apply to Objects - @Inject
Generally, you should wire your objects in this manner: using the @Inject annotation with an optional @Named to differentiate similarly-typed objects. This snippet is a member definition in a called MainViewController which is instantiated by the Guice-backed JavaFX ControllerFactory.@Inject private SettingsDAO settingsDAO;
Another example adds the @Named annotation. There are several String objects loaded by Guice and Guice cannot differentiate them based on type alone.
@Inject @Named("mathRecenteredJSONFile") private String mathRecenteredJSONFile;
Both of the injections produce objects that can be used throughout the classes' methods as they are available after the object is constructed. A special provision is needed if a constructor requires the value.
JavaFX Integration
When you're using FXML, FXMLLoader needs a factory to produce objects. Google Guice can be this factory. All you have to do is provide JavaFX with a handle to an Injector. In "Apply to Objects - Direct Call", you saw the Injector getting a Guice-enabled controller factory. This is the class referenced in that section. Nothing needs to appear in the Guice AbstractModule.package com.bekwam.javafx.guice; import com.google.inject.Injector; import javafx.util.Callback; import javax.inject.Inject; public class GuiceControllerFactory implements Callback, Object> { @Inject Injector injector; @Override public Object call(Class param) { return injector.getInstance(param); } }
Very simple
Dependency frameworks are important and can be deployed with a minimal footprint. Guice is a 700k pair of JARs (including the javax.inject annotations). Compared with other frameworks, that's a low download time, small diskspace usage, and reduced amount of JNLP and code signing.
No comments:
Post a Comment