From 6e725e5ec59eb3b07053286795db20c06679b252 Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 27 Jun 2025 16:18:01 -0400 Subject: [PATCH 1/2] add compile warnings to use lazy correctly now warns on compilation if missing a no args constructor --- .../java/io/avaje/inject/generator/BeanReader.java | 3 +++ .../java/io/avaje/inject/generator/MethodReader.java | 7 +++++-- inject/src/main/java/io/avaje/inject/Lazy.java | 10 +++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/BeanReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/BeanReader.java index 0193faec..47bf9f54 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/BeanReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/BeanReader.java @@ -1,6 +1,7 @@ package io.avaje.inject.generator; import static io.avaje.inject.generator.APContext.logError; +import static io.avaje.inject.generator.APContext.logWarn; import java.util.ArrayList; import java.util.Collections; @@ -194,6 +195,8 @@ BeanReader read() { conditions.addImports(importTypes); if (proxyLazy) { SimpleBeanLazyWriter.write(APContext.elements().getPackageOf(beanType), lazyProxyType); + } else if (lazy) { + logWarn(beanType, "Lazy beans should have a no-arg constructor"); } return this; } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java index d5a6f7b8..54ef5dd9 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java @@ -1,5 +1,6 @@ package io.avaje.inject.generator; +import static io.avaje.inject.generator.APContext.logWarn; import static io.avaje.inject.generator.Constants.CONDITIONAL_DEPENDENCY; import static io.avaje.inject.generator.ProcessingContext.asElement; @@ -169,13 +170,15 @@ void addDependsOnGeneric(Set set) { } MethodReader read() { - List ps = element.getParameters(); - for (VariableElement p : ps) { + var ps = element.getParameters(); + for (var p : ps) { params.add(new MethodParam(p)); } observeParameter = params.stream().filter(MethodParam::observeEvent).findFirst().orElse(null); if (proxyLazy) { SimpleBeanLazyWriter.write(APContext.elements().getPackageOf(element), lazyProxyType); + } else if (lazy) { + logWarn(element, "Lazy return types should be abstract or have a no-arg constructor"); } return this; } diff --git a/inject/src/main/java/io/avaje/inject/Lazy.java b/inject/src/main/java/io/avaje/inject/Lazy.java index 4e566598..f962e93d 100644 --- a/inject/src/main/java/io/avaje/inject/Lazy.java +++ b/inject/src/main/java/io/avaje/inject/Lazy.java @@ -6,13 +6,13 @@ import java.lang.annotation.Target; /** - * Marks a Singleton, Component or Factory method beans to be initialized lazily. + * Marks a class or factory method bean to be initialized lazily. * - *

When annotating a {@link Factory} as {@code @Lazy} it means that the factory itself is not - * lazy but all beans that it provides will have lazy initialization. + *

When annotating a {@link Factory} class as {@code @Lazy}, the factory itself is not lazy but + * all beans that it provides will have lazy initialization. * - *

If the annotated class is an interface or has an additional no-args constructor, a - * generated proxy bean will be wired for ultimate laziness. + *

If the annotated class or factory method is an interface or has an additional no-args + * constructor, a generated proxy bean will be wired for ultimate laziness. */ @Retention(RetentionPolicy.SOURCE) @Target({ElementType.METHOD, ElementType.TYPE}) From 3c0dcfbf7f17c824d14ed57cd4c563358e7f037b Mon Sep 17 00:00:00 2001 From: Josiah Noel <32279667+SentryMan@users.noreply.github.com> Date: Fri, 27 Jun 2025 13:44:34 -0700 Subject: [PATCH 2/2] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fd5f24bf..87dc0f8b 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,7 @@ public final class ExampleModule implements AvajeModule { - Specifically aimed for server-side development (rather than Android) - Supports "component testing" via `avaje-inject-test` and `@InjectTest` -- Provides API to obtain all bean instances that implement an interface +- 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 @@ -165,6 +165,7 @@ public final class ExampleModule implements AvajeModule { | [@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