Dependency Injection (DI) is a well-known design pattern that creates and binds dependent objects outside of a class. The technique nicely decouples dependencies from a main application class and enables developers to achieve high testability, maintainability, and extensibility. As I understand, Google Guice and Spring Framework are major DI frameworks in Java.
Unsurprisingly, working with a specific framework among others often causes a compatibility issue. Imagine you are developing an application using Guice for DI. Meanwhile, there is a third-party package that may accelerate your development effort, which actually relies on Spring unlike yours. Here, how can we apply Spring-based injection logic to Guice-based applications? An intermediate tool spring-guice could be a solution in this situation.
Dummy scenario: Machine learning application using Guice
Assume there is a Java-based machine learning framework that provides BaseModel
and BaseMetric
interface, and you have implemented LogisticRegression
model and Recall
metric on top of the framework. An ultimate goal for you is to implement the following BinaryClassification
application using Guice:
public class BinaryClassification {
@Inject
private BaseModel model;
@Inject
private BaseMetric metric;
...
}
Notice that such abstraction can be commonly seen in the community, and scikit-learn's BaseEstimator
is a good example. The actual implementation doesn't follow the DI design pattern in the formal sense though.
In Guice, the injectors can be triggered as:
Injector injector = Guice.createInjector(new ModelModule(), new MetricModule());
BinaryClassification app = injector.getInstance(BinaryClassification.class);
where the modules defining which model/metric to bind are:
public class ModelModule extends AbstractModule {
@Override
protected void configure() {
bind(BaseModel.class).to(LogisticRegression.class);
}
}
public class MetricModule extends AbstractModule {
@Override
protected void configure() {
bind(BaseMetric.class).to(Recall.class);
}
}
Leveraging a third-party application using Spring
As a UML diagram, the original implementation can be depicted:
Meanwhile, you found a novel RandomForest
implementation for the framework on GitHub, and it seems to be promising as an alternative to your LogisticRegression
model. However, unlike your own app, the third-party code depends on Spring to achieve DI and serves the custom application in the form of @Configuration
-annotated SpringAppConfig
module:
@Configuration
@ComponentScan("org.example.ml.app.spring") // RandomForest is in this path
public class SpringAppConfig {
}
In this situation, spring-guice enables you to easily apply the Spring-based injection logic to your Guice-based client application as follows:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.guice.module.SpringModule;
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(SpringAppConfig.class);
Injector injector = Guice.createInjector(new SpringModule(context), new MetricModule());
BinaryClassification app = injector.getInstance(BinaryClassification.class);
Eventually, the Spring module seamlessly replaces your LogisticRegression
with RandomForest
in the binary classification app.
Bottom line
"Dependency for Dependency Injection" is sometimes troublesome, especially when your application needs to interact with a number of third-party software that are out of your control. Of course, rewriting original Spring-based code with Guice could be a solution if the third-party implementation is simple enough, but it's not always the case. Hence, knowing one or more bridge tools helps us to consider the trade-off and make a better decision.
Last but not least, spring-guice has additional use cases that aren't covered by my example above, and their README highlights the multiple ways to fulfill the gap.
You can find a complete version of the sample code on GitHub: takuti-sandbox/spring-guice-test
Share
Categories
See also
- 2022-06-05
- Becoming Permanent Resident of Canada
- 2020-08-29
- What I Think About When I Talk About ML Product
- 2020-02-07
- Why a Data Science Engineer Becomes a Product Manager
Last updated: 2022-09-02
Author: Takuya Kitazawa
Takuya Kitazawa is a freelance software developer based in British Columbia, Canada. As a technologist specializing in AI and data-driven solutions, he has worked globally at Big Tech and start-up companies for a decade. At the intersection of tech and society, he is passionate about promoting the ethical use of information technologies through his mentoring, business consultation, and public engagement activities. See CV for more information, or contact at [email protected].
Now Gift a cup of coffeeDisclaimer
- Opinions are my own and do not represent the views of organizations I am/was belonging to.
- I am doing my best to ensure the accuracy and fair use of the information. However, there might be some errors, outdated information, or biased subjective statements because the main purpose of this blog is to jot down my personal thoughts as soon as possible before conducting an extensive investigation. Visitors understand the limitations and rely on any information at their own risk.
- That said, if there is any issue with the content, please contact me so I can take the necessary action.