Monthly Archives: September 2022

JSR-330: Framework-Agnostic Dependency Injection

In your project, you may have worked with Spring or you may have worked with Dagger. There are other popular dependency injection (DI) frameworks out there, and you select one for your project (I don’t think it’s encouraged to mix-and-match in the same project).

But if you’re writing a library for other projects to use, which DI framework should you standardize on? If you establish Spring as your DI framework, you discourage Dagger DI users, and vice-versa.

This is JSR-330 comes in.

JSR-330 is basically a small set of annotations to standardize DI. It does not implement DI; you’ll still need a DI framework to that. But it defines what classes are injectable/providable/bean-ifiable and where. This allows other users of your library to bring their own DI implementations with your project.

Here are the set of annotations that JSR-330 provides

JSR-330SpringDagger
@Inject@Autowired
@Named@Component@Component
@Qualifier@Qualifier
@Scope@Scope
@Singleton@Scope(“singleton”)@Singleton
@Scope(“prototype”)

As a small example, here’s a typical Spring DI setup

@org.springframework.stereotype.Component
public class Foo {
}

public class Bar {
@Autowire
public Bar(Foo foo) {
}
}

This is the same using JSR-330

@javax.inject.Named
public class Foo {
}

public class Bar {
@Inject
public Bar(Foo far) {
}
}

Note that the JSR-330 example will work in a Spring and Dagger project. However, the Spring example will only work in a Spring project.

There will be components that you will not be able to automatically inject. This may be a third-party class that you cannot just add a DI annotation to or some class that needs to be initialized in some custom way. For these, you’ll need to provide them via methods and unfortunately, you’ll need to rely on specific DI frameworks to do that.

Your library could then provide a package that helps others automatically provide those components.

For example, if Bar also needed a third-party DatabaseHandler, then you could provide a Spring configuration like this

@Configuration
public class DatabaseModule {
@Bean
public DatabaseHandler databaseHandler() {
return …
}
}

You may also provide a Dagger-friendly module for them to depend on as well

@Module
public class DatabaseModule {
@Provides
@Singleton
static DatabaseHandler provideDatabaseHandler() {
return …
}
}

Tagged , , ,

Grep cheatsheet

Find “some phrase” recursively from all files ending with .java

grep -r “some phrase” . –include=\*.java

Tagged