Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 8 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,6 @@ BeanScope beanScope = BeanScope.builder().build()
Example ex = beanScope.get(Example.class);
```

### Java Module Usage
When working with Java modules you need to add a `provides` statement in your `module-info.java` with the generated class.
```java
import io.avaje.inject.spi.InjectExtension;

module org.example {

requires io.avaje.inject;
// you must define the fully qualified class name of the generated classes. if you use an import statement, compilation will fail
provides InjectExtension with org.example.ExampleModule;
}
```

### Generated Wiring Class
The inject annotation processor determines the dependency wiring order and generates an `AvajeModule` class that calls all the generated DI classes.

Expand All @@ -80,18 +67,6 @@ The inject annotation processor determines the dependency wiring order and gener
@InjectModule
public final class ExampleModule implements AvajeModule {

private Builder builder;

@Override
public Class<?>[] classes() {
return new Class<?>[] {
org.example.DependencyClass.class,
org.example.DependencyClass2.class,
org.example.Example.class,
org.example.ExampleFactory.class,
};
}

/**
* 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
Expand All @@ -102,34 +77,34 @@ public final class ExampleModule implements AvajeModule {
this.builder = builder;
// create beans in order based on constructor dependencies
// i.e. "provides" followed by "dependsOn"
build_example_ExampleFactory();
build_example_DependencyClass();
build_example_DependencyClass2();
build_example_Example();
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() {
private void build_example_ExampleFactory(Builder builder) {
ExampleFactory$DI.build(builder);
}

@DependencyMeta(type = "org.example.DependencyClass")
private void build_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() {
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() {
private void build_example_Example(Builder builder) {
Example$DI.build(builder);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void readBeans(RoundEnvironment roundEnv) {
for (Data data : scopeAnnotations.values()) {
for (Element customBean : roundEnv.getElementsAnnotatedWith(data.type)) {
if (customBean instanceof TypeElement) {
ProcessingContext.processingOver(false);
data.scopeInfo.read((TypeElement) customBean, false, false);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static io.avaje.inject.generator.ProcessingContext.delayedElements;
import static io.avaje.inject.generator.ProcessingContext.loadMetaInfCustom;
import static io.avaje.inject.generator.ProcessingContext.loadMetaInfServices;
import static io.avaje.inject.generator.ProcessingContext.processingOver;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

Expand Down Expand Up @@ -71,6 +72,8 @@ public final class InjectProcessor extends AbstractProcessor {
private final Set<String> pluginFileProvided = new HashSet<>();
private final Set<String> moduleFileProvided = new HashSet<>();
private final List<ModuleData> moduleData = new ArrayList<>();
private int rounds;


@Override
public SourceVersion getSupportedSourceVersion() {
Expand Down Expand Up @@ -143,16 +146,14 @@ private List<String> lines(String relativeName) {

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.errorRaised()) {
if (processingOver() || roundEnv.errorRaised()) {
return false;
}
processingOver(rounds++ > 0);

APContext.setProjectModuleElement(annotations, roundEnv);
readModule(roundEnv);

final var processingOver = roundEnv.processingOver();
ProcessingContext.processingOver(processingOver);

readBeans(delayedElements());
addImportedAspects(importedAspects(roundEnv));
maybeElements(roundEnv, QualifierPrism.PRISM_TYPE).stream()
Expand Down Expand Up @@ -192,11 +193,12 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
maybeElements(roundEnv, ServiceProviderPrism.PRISM_TYPE).ifPresent(this::registerSPI);
maybeElements(roundEnv, PluginProvidesPrism.PRISM_TYPE).ifPresent(this::registerSPI);
allScopes.readBeans(roundEnv);
defaultScope.write(processingOver);
allScopes.write(processingOver);
final var over = processingOver();
defaultScope.write(over);
allScopes.write(over);

if (processingOver) {
var order =
if (processingOver()) {
final var order =
new FactoryOrder(ProcessingContext.modules(), defaultScope.pluginProvided())
.orderModules();

Expand Down Expand Up @@ -234,8 +236,13 @@ private void validateQualifier(ExecutableElement method) {
}

// Optional because these annotations are not guaranteed to exist
private static Optional<? extends Set<? extends Element>> maybeElements(RoundEnvironment round, String name) {
return Optional.ofNullable(typeElement(name)).map(round::getElementsAnnotatedWith);
private Optional<? extends Set<? extends Element>> maybeElements(RoundEnvironment round, String name) {
final var op = Optional.ofNullable(typeElement(name))
.map(round::getElementsAnnotatedWith);

// reset processingOver flag if anything needs processing in this round
processingOver(processingOver() && op.filter(n -> !n.isEmpty()).isEmpty());
return op;
}

private Set<TypeElement> importedElements(RoundEnvironment roundEnv) {
Expand Down Expand Up @@ -264,7 +271,7 @@ private boolean notAlreadyProvided(TypeElement e) {
return !moduleFileProvided.contains(type) && !pluginFileProvided.contains(type);
}

private static Map<String, AspectImportPrism> importedAspects(RoundEnvironment roundEnv) {
private Map<String, AspectImportPrism> importedAspects(RoundEnvironment roundEnv) {
return maybeElements(roundEnv, AspectImportPrism.PRISM_TYPE).stream()
.flatMap(Set::stream)
.map(AspectImportPrism::getAllInstancesOn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,7 @@ static Set<TypeElement> delayedElements() {
}

static boolean delayUntilNextRound(TypeElement element) {
if (!processingOver) {
CTX.get().delayQueue.add(element);
}
return !processingOver;
return CTX.get().delayQueue.add(element);
}

static void clear() {
Expand Down Expand Up @@ -263,6 +260,10 @@ static void processingOver(boolean over) {
processingOver = over;
}

static boolean processingOver() {
return processingOver;
}

static void writeSPIServicesFile() {
addEventSPI();
readExistingMetaInfServices();
Expand Down