Skip to content

avaje/avaje-inject

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Discord Build JDK EA License Maven Central javadoc

APT-based dependency injection for server-side developers - https://avaje.io/inject

Quick Start

1. Add avaje-inject as a dependency.

<dependency> <groupId>io.avaje</groupId> <artifactId>avaje-inject</artifactId> <version>${avaje.inject.version}</version> </dependency>

2. Add avaje-inject-generator annotation processor as a dependency with provided scope.

<dependency> <groupId>io.avaje</groupId> <artifactId>avaje-inject-generator</artifactId> <version>${avaje.inject.version}</version> <scope>provided</scope> </dependency>

3. Create a Bean Class annotated with @Singleton

@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:

@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.

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.

@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

  • 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 @Singleton @Component, @Service, @Repository
Provider<T> Provider<T> FactoryBean<T>
@Inject @Inject @Inject, @Autowired
@Inject @Nullable or @Inject Optional<T> @Inject @Nullable @Autowired(required=false)
@Qualifier/@Named @Qualifier/@Named @Qualifier
@AssistFactory @AssistedFactory -
@PostConstruct - @PostConstruct
@PreDestroy - @PreDestroy
@Factory and @Bean - @Configuration and @Bean
@RequiresBean and @RequiresProperty - @Conditional
@Lazy - @Lazy
@Prototype - @Scope("prototype")
@Primary - @Primary
@Secondary - @Fallback
@InjectTest - @SpringBootTest