https://github.com/avaje/avaje-inject
Dependency injection via source code generation
https://github.com/avaje/avaje-inject
annotation-processing apt avaje dagger dependency-injection di-library dinject inversion-of-control jakarta-inject java javax-inject kapt kotlin
Last synced: 19 days ago
JSON representation
Dependency injection via source code generation
- Host: GitHub
- URL: https://github.com/avaje/avaje-inject
- Owner: avaje
- License: apache-2.0
- Created: 2018-11-07T21:56:19.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2026-01-19T18:33:38.000Z (23 days ago)
- Last Synced: 2026-01-20T00:49:23.890Z (23 days ago)
- Topics: annotation-processing, apt, avaje, dagger, dependency-injection, di-library, dinject, inversion-of-control, jakarta-inject, java, javax-inject, kapt, kotlin
- Language: Java
- Homepage: https://avaje.io/inject
- Size: 3.42 MB
- Stars: 296
- Watchers: 7
- Forks: 28
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-java - Avaje Inject
README
[](https://discord.gg/Qcqf9R27BR)
[](https://github.com/avaje/avaje-inject/actions/workflows/build.yml)
[](https://github.com/avaje/avaje-inject/actions/workflows/jdk-ea.yml)
[](https://github.com/avaje/avaje-inject/blob/master/LICENSE)
[](https://mvnrepository.com/artifact/io.avaje/avaje-inject)
[](https://javadoc.io/doc/io.avaje/avaje-inject)
# [Avaje-Inject](https://avaje.io/inject)
APT-based dependency injection for server-side developers - https://avaje.io/inject
## Quick Start
#### 1. Add avaje-inject as a dependency.
```xml
io.avaje
avaje-inject
${avaje.inject.version}
```
#### 2. Add avaje-inject-generator annotation processor as a dependency with provided scope.
```xml
io.avaje
avaje-inject-generator
${avaje.inject.version}
provided
```
#### 3. Create a Bean Class annotated with @Singleton
```java
@Singleton
public class Example {
private DependencyClass d1;
private DependencyClass2 d2;
// Dependencies must be annotated with singleton,
// or else be provided from another class annotated with @Factory
public Example(DependencyClass d1, DependencyClass2 d2) {
this.d1 = d1;
this.d2 = d2;
}
}
```
Example factory class:
```java
@Factory
public class ExampleFactory {
@Bean
public DependencyClass2 bean() {
return new DependencyClass2();
}
}
```
#### 4. Use BeanScope to wire and retrieve the beans and use them however you wish.
```java
BeanScope beanScope = BeanScope.builder().build()
Example ex = beanScope.get(Example.class);
```
### Generated Wiring Class
The inject annotation processor determines the dependency wiring order and generates an `AvajeModule` class that calls all the generated DI classes.
```java
@Generated("io.avaje.inject.generator")
@InjectModule
public final class ExampleModule implements AvajeModule {
/**
* Creates all the beans in order based on constructor dependencies. The beans are registered
* into the builder along with callbacks for field/method injection, and lifecycle
* support.
*/
@Override
public void build(Builder builder) {
this.builder = builder;
// create beans in order based on constructor dependencies
// i.e. "provides" followed by "dependsOn"
build_example_ExampleFactory(builder);
build_example_DependencyClass(builder);
build_example_DependencyClass2(builder);
build_example_Example(builder);
}
@DependencyMeta(type = "org.example.ExampleFactory")
private void build_example_ExampleFactory(Builder builder) {
ExampleFactory$DI.build(builder);
}
@DependencyMeta(type = "org.example.DependencyClass")
private void build_example_DependencyClass(Builder builder) {
DependencyClass$DI.build(builder);
}
@DependencyMeta(
type = "org.example.DependencyClass2",
method = "org.example.ExampleFactory$DI.build_bean", // factory method
dependsOn = {"org.example.ExampleFactory"}) //factory beans naturally depend on the factory
private void build_example_DependencyClass2(Builder builder) {
ExampleFactory$DI.build_bean(builder);
}
@DependencyMeta(
type = "org.example.Example",
dependsOn = {"org.example.DependencyClass", "org.example.DependencyClass2"})
private void build_example_Example(Builder builder) {
Example$DI.build(builder);
}
}
```
## Similar to [Dagger](https://google.github.io/dagger/)
- Uses Java annotation processing for dependency injection
- Generates source code
- Avoids any use of reflection or classpath scanning (so low overhead and fast startup)
## Differences to Dagger
- Specifically aimed for server-side development (rather than Android)
- Supports "component testing" via `avaje-inject-test` and `@InjectTest`
- Provides an API to obtain all bean instances that implement an interface
- Lifecycle methods with `@PostConstruct` and `@PreDestroy`
- Spring-like factory classes with `@Factory` and `@Bean`
- Conditional Wiring based on active profiles or existing beans/properties
## DI Framework comparison
| Avaje | Dagger | Spring
| :--- | :--- | :--- |
| [@Singleton](https://avaje.io/inject/#singleton) | @Singleton | @Component, @Service, @Repository |
| [Provider<T>](https://avaje.io/inject/#provider) | Provider<T> | FactoryBean<T>
| [@Inject](https://avaje.io/inject/#inject) | @Inject | @Inject, @Autowired
| [@Inject @Nullable](https://avaje.io/inject/#nullable) or [@Inject Optional<T>](https://avaje.io/inject/#optional) | @Inject @Nullable | @Autowired(required=false)
| [@Qualifier/@Named](https://avaje.io/inject/#qualifiers) | @Qualifier/@Named | @Qualifier
| [@AssistFactory](https://avaje.io/inject/#assistInject) | @AssistedFactory | - |
| [@PostConstruct](https://avaje.io/inject/#post-construct) | - | @PostConstruct
| [@PreDestroy](https://avaje.io/inject/#pre-destroy) | - | @PreDestroy
| [@Factory and @Bean](https://avaje.io/inject/#factory) | - | @Configuration and @Bean
| [@RequiresBean and @RequiresProperty](https://avaje.io/inject/#conditional) | - | @Conditional
| [@Lazy](https://avaje.io/inject/#lazy) | - | @Lazy
| [@Prototype](https://avaje.io/inject/#prototype) | - | @Scope("prototype")
| [@Primary](https://avaje.io/inject/#primary) | - | @Primary
| [@Secondary](https://avaje.io/inject/#secondary) | - | @Fallback
| [@InjectTest](https://avaje.io/inject/#component-testing) | - | @SpringBootTest