Skip to content

Commit 300cdbb

Browse files
committed
Merge remote-tracking branch 'upstream/master' into postConstructBeans
2 parents 1f7f05e + fa79dda commit 300cdbb

File tree

17 files changed

+146
-18
lines changed

17 files changed

+146
-18
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@ build/
1313
inject-generator/avaje-inject
1414
inject-generator/avaje-inject-generator
1515
inject-generator/avaje-processors.txt
16+
inject-generator/avaje-module-dependencies.csv
17+
inject-generator/avaje-plugins.csv
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package org.other.one;
2+
3+
public class OtherComponent3 {}

blackbox-test-inject/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
<dependency>
6060
<groupId>io.github.resilience4j</groupId>
6161
<artifactId>resilience4j-annotations</artifactId>
62-
<version>2.2.0</version>
62+
<version>2.3.0</version>
6363
</dependency>
6464

6565
<!-- annotation processor -->

blackbox-test-inject/src/main/java/org/example/myapp/ConfigPropertiesPlugin.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,18 @@
22

33
import io.avaje.config.Config;
44
import io.avaje.inject.Component;
5+
import io.avaje.inject.Component.Import.Kind;
56
import io.avaje.inject.spi.ConfigPropertyPlugin;
67

78
import io.avaje.spi.ServiceProvider;
89
import org.other.one.OtherComponent2;
10+
import org.other.one.OtherComponent3;
911

1012
import java.util.Optional;
1113

1214
@ServiceProvider
1315
@Component.Import(value = OtherComponent2.class)
16+
@Component.Import(value = OtherComponent3.class, kind = Kind.LAZY)
1417
public class ConfigPropertiesPlugin implements ConfigPropertyPlugin {
1518

1619
@Override
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.example.myapp;
2+
3+
import java.util.concurrent.atomic.AtomicInteger;
4+
5+
public class MyNestedDestroy {
6+
7+
public static AtomicInteger started = new AtomicInteger();
8+
public static AtomicInteger stopped = new AtomicInteger();
9+
10+
public static void reset() {
11+
started.set(0);
12+
stopped.set(0);
13+
}
14+
15+
public void start() {
16+
started.incrementAndGet();
17+
}
18+
19+
public Reaper reaper() {
20+
return new Reaper();
21+
}
22+
23+
public static class Reaper {
24+
25+
public void stop() {
26+
stopped.incrementAndGet();
27+
}
28+
}
29+
}

blackbox-test-inject/src/main/java/org/example/myapp/config/AFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
import io.avaje.inject.Bean;
44
import io.avaje.inject.Factory;
5+
import org.example.myapp.MyNestedDestroy;
56

67
import java.io.IOException;
78

89
@Factory
910
class AFactory {
1011

12+
@Bean(initMethod = "start", destroyMethod = "reaper().stop()")
13+
MyNestedDestroy lifecycle2() {
14+
return new MyNestedDestroy();
15+
}
16+
1117
@Bean
1218
A0.Builder build0() {
1319
return new I0();

blackbox-test-inject/src/test/java/org/example/myapp/HelloServiceTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@
1414

1515
class HelloServiceTest {
1616

17+
@Test
18+
void lifecycles() {
19+
MyNestedDestroy.reset();
20+
try (BeanScope beanScope = BeanScope.builder().build()) {
21+
assertThat(beanScope.get(MyNestedDestroy.class)).isNotNull();
22+
assertThat(MyNestedDestroy.started.get()).isEqualTo(1);
23+
assertThat(MyNestedDestroy.stopped.get()).isEqualTo(0);
24+
}
25+
assertThat(MyNestedDestroy.stopped.get()).isEqualTo(1);
26+
}
27+
1728
/**
1829
* No mocking, no use of <code>@TestScope</code> so just like main.
1930
*/

blackbox-test-inject/src/test/java/org/example/myapp/testconfig/CountTestScopeStart.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,5 @@ public void onStart() {
1313

1414
public void onStop() {
1515
stopped.incrementAndGet();
16-
System.out.println("STOPPED !! ");
1716
}
1817
}

inject-generator/src/main/java/io/avaje/inject/generator/InjectProcessor.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,12 +211,23 @@ private Set<TypeElement> importedElements(RoundEnvironment roundEnv) {
211211
return maybeElements(roundEnv, ImportPrism.PRISM_TYPE).stream()
212212
.flatMap(Set::stream)
213213
.map(ImportPrism::getInstanceOn)
214-
.flatMap(p -> p.value().stream())
215-
.map(ProcessingContext::asElement)
216-
.filter(this::notAlreadyProvided)
214+
.flatMap(p -> {
215+
var kind = p.kind();
216+
return p.value().stream()
217+
.map(ProcessingContext::asElement)
218+
.filter(this::notAlreadyProvided)
219+
.map(e -> registerImportedKind(e, kind));
220+
})
217221
.collect(Collectors.toSet());
218222
}
219223

224+
private static TypeElement registerImportedKind(TypeElement e, String kind) {
225+
if (!"SINGLETON".equals(kind)) {
226+
ProcessingContext.addImportedKind(e, kind);
227+
}
228+
return e;
229+
}
230+
220231
private boolean notAlreadyProvided(TypeElement e) {
221232
final String type = e.getQualifiedName().toString();
222233
return !moduleFileProvided.contains(type) && !pluginFileProvided.contains(type);

inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ void builderBuildAddBean(Append writer) {
287287
if (hasInitMethod) {
288288
var addPostConstruct =
289289
multiRegister
290-
? " .peek(b -> builder.addPostConstruct(b::%s))"
290+
? " .peek($bean -> builder.addPostConstruct($bean::%s))"
291291
: "builder.addPostConstruct($bean::%s);";
292292
writer.indent(indent).append(addPostConstruct, initMethod).eol();
293293
}
@@ -296,14 +296,14 @@ void builderBuildAddBean(Append writer) {
296296
if (notEmpty(destroyMethod)) {
297297
var addPreDestroy =
298298
multiRegister
299-
? " .forEach(b -> builder.addPreDestroy(b::%s%s));"
300-
: "builder.addPreDestroy($bean::%s%s);";
301-
writer.indent(indent).append(addPreDestroy, destroyMethod, priority).eol();
299+
? " .forEach($bean -> builder.addPreDestroy(%s%s));"
300+
: "builder.addPreDestroy(%s%s);";
301+
writer.indent(indent).append(addPreDestroy, addPreDestroy(destroyMethod), priority).eol();
302302

303303
} else if (typeReader != null && typeReader.isClosable()) {
304304
var addPreDestroy =
305305
multiRegister
306-
? " .forEach(b -> builder.addPreDestroy(b::close%s));"
306+
? " .forEach($bean -> builder.addPreDestroy($bean::close%s));"
307307
: "builder.addPreDestroy($bean::close%s);";
308308
writer.indent(indent).append(addPreDestroy, priority).eol();
309309

@@ -324,6 +324,13 @@ void builderBuildAddBean(Append writer) {
324324
}
325325
}
326326

327+
static String addPreDestroy(String destroyMethod) {
328+
if (!destroyMethod.contains(".")) {
329+
return "$bean::" + destroyMethod;
330+
}
331+
return "() -> $bean." + destroyMethod;
332+
}
333+
327334
private boolean hasLifecycleMethods() {
328335
return notEmpty(initMethod) || notEmpty(destroyMethod) || (typeReader != null && typeReader.isClosable() || beanCloseable);
329336
}

inject-generator/src/main/java/io/avaje/inject/generator/ProcessingContext.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ private ProcessingContext() {}
2727
static final class Ctx {
2828
private final Set<String> uniqueModuleNames = new HashSet<>();
2929
private final Set<String> providedTypes = new HashSet<>();
30+
private final Map<String, String> importedProtoTypes = new HashMap<>();
3031
private final Set<String> optionalTypes = new LinkedHashSet<>();
3132
private final Map<String, AspectImportPrism> aspectImportPrisms = new HashMap<>();
3233
private final List<ModuleData> modules = new ArrayList<>();
@@ -154,6 +155,22 @@ static void addOptionalType(String paramType, String name) {
154155
}
155156
}
156157

158+
static void addImportedKind(TypeElement element, String kind) {
159+
CTX.get().importedProtoTypes.put(element.getQualifiedName().toString(), kind);
160+
}
161+
162+
static boolean isImportedPrototype(TypeElement element) {
163+
return "prototype".equalsIgnoreCase(importedTypeKind(element));
164+
}
165+
166+
static boolean isImportedLazy(TypeElement element) {
167+
return "lazy".equalsIgnoreCase(importedTypeKind(element));
168+
}
169+
170+
private static String importedTypeKind(TypeElement element) {
171+
return CTX.get().importedProtoTypes.get(element.getQualifiedName().toString());
172+
}
173+
157174
static void addImportedAspects(Map<String, AspectImportPrism> importedMap) {
158175
CTX.get().aspectImportPrisms.putAll(importedMap);
159176
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.avaje.inject.generator;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.assertj.core.api.Assertions.assertThat;
6+
7+
class MethodReaderTest {
8+
9+
@Test
10+
void addPreDestroy() {
11+
assertThat(MethodReader.addPreDestroy("close")).isEqualTo("$bean::close");
12+
assertThat(MethodReader.addPreDestroy("foo")).isEqualTo("$bean::foo");
13+
}
14+
15+
@Test
16+
void addPreDestroyNested() {
17+
assertThat(MethodReader.addPreDestroy("foo().bar()")).isEqualTo("() -> $bean.foo().bar()");
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package io.avaje.inject.generator.models.valid.imported;
2+
3+
import io.avaje.inject.Component;
4+
import io.avaje.inject.Component.Import.Kind;
5+
6+
@Component.Import(value = ImportedProtoType.class, kind = Kind.PROTOTYPE)
7+
public class ImportedProtoType {}

inject-test/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
<properties>
1414
<jupiter.version>5.11.4</jupiter.version>
15-
<mockito.version>5.14.2</mockito.version>
15+
<mockito.version>5.15.2</mockito.version>
1616
</properties>
1717

1818
<dependencies>

inject/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
<dependency>
5454
<groupId>org.mockito</groupId>
5555
<artifactId>mockito-core</artifactId>
56-
<version>5.14.2</version>
56+
<version>5.15.2</version>
5757
<optional>true</optional>
5858
</dependency>
5959

inject/src/main/java/io/avaje/inject/Component.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package io.avaje.inject;
22

3+
import java.lang.annotation.Repeatable;
34
import java.lang.annotation.Retention;
45
import java.lang.annotation.Target;
56

67
import static java.lang.annotation.ElementType.*;
7-
import static java.lang.annotation.RetentionPolicy.CLASS;
88
import static java.lang.annotation.RetentionPolicy.RUNTIME;
9+
import static java.lang.annotation.RetentionPolicy.SOURCE;
910

1011
/**
1112
* Identify a bean as component with singleton scope that avaje-inject will use.
@@ -63,13 +64,26 @@
6364
*
6465
* }</pre>
6566
*/
66-
@Retention(CLASS)
67+
@Retention(SOURCE)
6768
@Target({TYPE, PACKAGE, MODULE})
69+
@Repeatable(Imports.class)
6870
@interface Import {
6971

70-
/**
71-
* Types to generate DI classes for.
72-
*/
72+
/** Types to generate DI classes for. */
7373
Class<?>[] value();
74+
75+
/** What kind of bean */
76+
Kind kind() default Kind.SINGLETON;
77+
78+
enum Kind { SINGLETON, PROTOTYPE, LAZY }
79+
}
80+
81+
/**
82+
* @see Import
83+
*/
84+
@Retention(SOURCE)
85+
@Target({TYPE, PACKAGE, MODULE})
86+
@interface Imports {
87+
Import[] value();
7488
}
7589
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
<dependency>
7474
<groupId>org.mockito</groupId>
7575
<artifactId>mockito-core</artifactId>
76-
<version>5.14.2</version>
76+
<version>5.15.2</version>
7777
<scope>test</scope>
7878
</dependency>
7979
</dependencies>

0 commit comments

Comments
 (0)