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 5b6df4591..0193faec6 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 @@ -263,6 +263,14 @@ Set allGenericTypes() { if (utype.isGeneric()) { allUTypes.add(utype); } + method.params().stream() + .filter(p -> !p.observeEvent()) + .map(MethodParam::getFullUType) + .forEach(u -> { + if (u.isGeneric()) { + allUTypes.add(u); + } + }); } if (constructor != null) { 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 5b44ddc53..d5a6f7b89 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 @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -419,6 +420,11 @@ void addImports(ImportTypeMap importTypes) { if (optionalType) { importTypes.add(Constants.OPTIONAL); } + + if (observeParameter != null && params.size() > 1) { + importTypes.add(Supplier.class.getCanonicalName()); + importTypes.add(Constants.BEANSCOPE); + } conditions.addImports(importTypes); } diff --git a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java index 2b7fa0160..4095ecd5e 100644 --- a/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java +++ b/inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java @@ -256,6 +256,7 @@ private void writeExtraInjection() { private void writeObserveMethods() { final var bean = "bean"; final var builder = "builder"; + final var scope = "beanScope"; final var indent = " "; for (MethodReader methodReader : beanReader.observerMethods()) { @@ -264,9 +265,18 @@ private void writeObserveMethods() { final var shortWithoutAnnotations = observeUtype.shortWithoutAnnotations(); var injectParams = methodReader.params().stream().skip(1).collect(toList()); + if (!injectParams.isEmpty()) { + writer.indent(indent).append("var %s = %s.get(BeanScope.class);", scope, builder).eol(); + } + for (MethodParam param : injectParams) { - writer.indent(indent).append("var %s = ", methodReader.name() + "$" + param.simpleName()); - param.builderGetDependency(writer, builder); + if (Constants.BEANSCOPE.equals(param.getFullUType().fullWithoutAnnotations())) { + continue; + } + writer.indent(indent).append("Supplier<%s> %s = () -> ", + param.getFullUType().shortType(), + methodReader.name() + "$" + param.simpleName()); + param.builderGetDependency(writer, scope); writer.append(";").eol(); } @@ -281,7 +291,10 @@ private void writeObserveMethods() { writer.append("%s::%s;", bean, methodReader.name()); } else { var injectParamNames = injectParams.stream() - .map(p -> methodReader.name() + "$" + p.simpleName()) + .map(p -> + Constants.BEANSCOPE.equals(p.getFullUType().fullWithoutAnnotations()) + ? scope + : methodReader.name() + "$" + p.simpleName() + ".get()") .collect(joining(", ")); writer.append("e -> bean.%s(e, %s);", methodReader.name(), injectParamNames); } diff --git a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/observes/TestObserverInjection.java b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/observes/TestObserverInjection.java index 3c3a18e35..dcc88b080 100644 --- a/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/observes/TestObserverInjection.java +++ b/inject-generator/src/test/java/io/avaje/inject/generator/models/valid/observes/TestObserverInjection.java @@ -1,10 +1,11 @@ package io.avaje.inject.generator.models.valid.observes; +import io.avaje.inject.BeanScope; import io.avaje.inject.events.ObservesAsync; import jakarta.inject.Singleton; @Singleton public class TestObserverInjection { - void observe(@ObservesAsync String e, TestObserver observer) {} + void observe(@ObservesAsync String e, TestObserver observer, BeanScope scope) {} } diff --git a/inject-test/src/test/java/org/example/observes/MyObserverInjectPrototype.java b/inject-test/src/test/java/org/example/observes/MyObserverInjectPrototype.java new file mode 100644 index 000000000..be5d238a6 --- /dev/null +++ b/inject-test/src/test/java/org/example/observes/MyObserverInjectPrototype.java @@ -0,0 +1,22 @@ +package org.example.observes; + +import java.util.ArrayDeque; + +import org.example.coffee.prototype.MyProto; + +import io.avaje.inject.events.Observes; +import jakarta.inject.Singleton; + +@Singleton +public class MyObserverInjectPrototype { + + boolean invoked = false; + CustomEvent event; + ArrayDeque beansList = new ArrayDeque<>(); + + void observe(@Observes CustomEvent e, MyProto proto) { + invoked = true; + event = e; + beansList.add(proto); + } +} diff --git a/inject-test/src/test/java/org/example/observes/MyObserverInjected.java b/inject-test/src/test/java/org/example/observes/MyObserverInjected.java index a1a4c96c8..0ee4d3795 100644 --- a/inject-test/src/test/java/org/example/observes/MyObserverInjected.java +++ b/inject-test/src/test/java/org/example/observes/MyObserverInjected.java @@ -1,5 +1,6 @@ package org.example.observes; +import io.avaje.inject.events.Event; import io.avaje.inject.events.Observes; import jakarta.inject.Singleton; @@ -9,7 +10,10 @@ public class MyObserverInjected { boolean invoked = false; CustomEvent event; - void observe(@Observes CustomEvent e, MyObserver observer) { + void observe( + @Observes CustomEvent e, + MyObserver observer, + @StrQualifier(value = "foo") Event publisher) { invoked = true; event = e; } diff --git a/inject-test/src/test/java/org/example/observes/TestEventMessaging.java b/inject-test/src/test/java/org/example/observes/TestEventMessaging.java index d8603a01f..410210b8e 100644 --- a/inject-test/src/test/java/org/example/observes/TestEventMessaging.java +++ b/inject-test/src/test/java/org/example/observes/TestEventMessaging.java @@ -16,6 +16,7 @@ class TestEventMessaging { @Inject MyObserver observer; @Inject MyQualifiedObserver qualifiedObserver; @Inject MyObserverInjected observerInjected; + @Inject MyObserverInjectPrototype observerPrototype; @Inject MyStrQualifiedObserver strQualifiedObserver; @Inject Event event; @Inject EventSender2 sender2; @@ -30,6 +31,9 @@ void before() { qualifiedObserver.event = null; observerInjected.invoked= false; observerInjected.event = null; + observerPrototype.invoked = false; + observerPrototype.event = null; + observerPrototype.beansList.clear(); } @Test @@ -45,6 +49,21 @@ void test() { assertThat(observerInjected.event).isSameAs(message); } + @Test + void testProtoType() { + var message = new CustomEvent("hi"); + + event.fire(message); + + assertThat(observerPrototype.invoked).isTrue(); + assertThat(observerPrototype.event).isSameAs(message); + event.fire(message); + + assertThat(observerPrototype.invoked).isTrue(); + assertThat(observerPrototype.event).isSameAs(message); + assertThat(observerPrototype.beansList.poll()).isNotSameAs(observerPrototype.beansList.poll()); + } + @Test void testWithQualified() { var message = new CustomEvent("hi");