Skip to content

PostConstruct method Direct Injection #752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 6, 2025
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.example.myapp.config;

import io.avaje.inject.PostConstruct;
import jakarta.inject.Named;
import jakarta.inject.Singleton;

@Singleton
public class LifeFour {

public String _state;

@PostConstruct
void post(@Named("foo") LifeOne one, LifeTwo two) {
_state = "post|"
+ (one != null ? "one|" : "")
+ (two != null ? "two" : "");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.example.myapp.config;

import io.avaje.inject.BeanScope;
import io.avaje.inject.PostConstruct;
import jakarta.inject.Singleton;

@Singleton
public class LifeOne {

public String _state;

@PostConstruct
void post(BeanScope scope) {
_state = "post|"
+ (scope != null ? "scope" : "");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.example.myapp.config;

import io.avaje.inject.BeanScope;
import io.avaje.inject.PostConstruct;
import io.avaje.inject.Prototype;

@Prototype
public class LifeProtoTwo {

public String _state;

@PostConstruct
void post(LifeOne one, BeanScope scope) {
_state = "post|"
+ (one != null ? "one|" : "")
+ (scope != null ? "scope" : "");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.example.myapp.config;

import io.avaje.inject.PostConstruct;
import jakarta.inject.Singleton;

@Singleton
public class LifeThree {

public String _state;

@PostConstruct
void post(LifeOne one) {
_state = "post|"
+ (one != null ? "one" : "");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.example.myapp.config;

import io.avaje.inject.BeanScope;
import io.avaje.inject.PostConstruct;
import jakarta.inject.Singleton;

@Singleton
public class LifeTwo {

public String _state;

@PostConstruct
void post(LifeOne one, BeanScope scope) {
_state = "post|"
+ (one != null ? "one|" : "")
+ (scope != null ? "scope" : "");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.example.myapp.config;

import io.avaje.inject.BeanScope;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class PostConstructParametersTest {

@Test
void factorySecondaryAsProvider() {
try (BeanScope testScope = BeanScope.builder().build()) {
var one = testScope.get(LifeOne.class);
var two = testScope.get(LifeTwo.class);
var three = testScope.get(LifeThree.class);
var four = testScope.get(LifeFour.class);
var protoTwo = testScope.get(LifeProtoTwo.class);

assertThat(one._state).isEqualTo("post|scope");
assertThat(two._state).isEqualTo("post|one|scope");
assertThat(three._state).isEqualTo("post|one");
assertThat(four._state).isEqualTo("post|one|two");
assertThat(protoTwo._state).isEqualTo("post|one|scope");
}
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.avaje.inject.generator;

import static io.avaje.inject.generator.APContext.logError;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
Expand All @@ -11,7 +10,6 @@
import java.util.stream.Stream;

import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;

Expand All @@ -30,7 +28,7 @@ final class BeanReader {
private final List<MethodReader> injectMethods;
private final List<MethodReader> factoryMethods;
private final List<MethodReader> observerMethods;
private final Element postConstructMethod;
private final Optional<MethodReader> postConstructMethod;
private final Element preDestroyMethod;

private final ImportTypeMap importTypes = new ImportTypeMap();
Expand Down Expand Up @@ -165,6 +163,8 @@ BeanReader read() {
factoryMethod.addImports(importTypes);
}

postConstructMethod.ifPresent(m -> m.addImports(importTypes));

conditions.addImports(importTypes);
return this;
}
Expand Down Expand Up @@ -242,6 +242,12 @@ Set<UType> allGenericTypes() {
for (MethodReader factoryMethod : factoryMethods()) {
factoryMethod.addDependsOnGeneric(allUTypes);
}

postConstructMethod.ifPresent(m ->
m.params().stream()
.filter(MethodParam::isGenericParam)
.map(MethodParam::getFullUType)
.forEach(allUTypes::add));
return allUTypes;
}

Expand All @@ -266,7 +272,7 @@ String metaKey() {
* Return true if lifecycle via annotated methods is required.
*/
boolean hasLifecycleMethods() {
return (postConstructMethod != null || preDestroyMethod != null || typeReader.isClosable());
return (postConstructMethod.isPresent() || preDestroyMethod != null || typeReader.isClosable());
}

List<MetaData> createFactoryMethodMeta() {
Expand Down Expand Up @@ -327,9 +333,10 @@ void buildRegister(Append writer) {
}

void addLifecycleCallbacks(Append writer, String indent) {
if (postConstructMethod != null && !registerProvider()) {
writer.indent(indent).append(" builder.addPostConstruct($bean::%s);", postConstructMethod.getSimpleName()).eol();
if (postConstructMethod.isPresent() && !registerProvider()) {
writePostConstruct(writer, indent, postConstructMethod.get());
}

if (preDestroyMethod != null) {
lifeCycleNotSupported("@PreDestroy");
var priority = preDestroyPriority == null || preDestroyPriority == 1000 ? "" : ", " + preDestroyPriority;
Expand All @@ -339,17 +346,46 @@ void addLifecycleCallbacks(Append writer, String indent) {
}
}

private void writePostConstruct(Append writer, String indent, MethodReader postConstruct) {
writer.indent(indent).append(" builder.addPostConstruct(");
final var methodName = postConstruct.name();
final var params = postConstruct.params();
if (params.isEmpty() || Constants.BEANSCOPE.equals(params.get(0).getFullUType().shortType())) {
writer.append("$bean::%s);", methodName).eol();
} else {
writer.append("beanScope -> $bean.%s(", methodName);
writeLifeCycleGet(writer, params, "beanScope", "beanScope");
writer.append(");").eol();
}
}

void prototypePostConstruct(Append writer, String indent) {
if (postConstructMethod != null) {
var postConstruct = (ExecutableElement) postConstructMethod;
writer.indent(indent).append(" bean.%s(", postConstructMethod.getSimpleName());
if (postConstruct.getParameters().isEmpty()) {
postConstructMethod.ifPresent(m -> {
writer.indent(indent).append(" bean.%s(", m.name());
if (m.params().isEmpty()) {
writer.append(");").eol();
} else {
writer.append("builder.get(io.avaje.inject.BeanScope.class));").eol();
writeLifeCycleGet(writer, m.params(), "builder", "builder.get(io.avaje.inject.BeanScope.class)");
writer.append(";").eol();
}
writer.eol();
});
}

private void writeLifeCycleGet(Append writer, List<MethodParam> params, String builderName, String beanScopeString) {
final var size = params.size();
for (int i = 0; i < size; i++) {
if (i > 0) {
writer.append(", ");
}
final var param = params.get(i);
if (Constants.BEANSCOPE.equals(param.getFullUType().fullWithoutAnnotations())) {
writer.append(beanScopeString);
} else {
param.builderGetDependency(writer, builderName);
}
}
writer.append(")");
}

private void lifeCycleNotSupported(String lifecycle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class TypeExtendsInjection {
private final TypeElement baseType;
private final boolean factory;
private final List<AspectPair> typeAspects;
private Element postConstructMethod;
private Optional<MethodReader> postConstructMethod = Optional.empty();
private Element preDestroyMethod;
private Integer preDestroyPriority;

Expand Down Expand Up @@ -125,7 +125,7 @@ private void readMethod(Element element, TypeElement type) {
notInjectMethods.add(methodKey);
}
if (AnnotationUtil.hasAnnotationWithName(element, "PostConstruct")) {
postConstructMethod = element;
postConstructMethod = Optional.of(new MethodReader(methodElement, type, importTypes).read());
checkAspect = false;
}
if (AnnotationUtil.hasAnnotationWithName(element, "PreDestroy")) {
Expand Down Expand Up @@ -206,7 +206,7 @@ List<MethodReader> observerMethods() {
return observerMethods;
}

Element postConstructMethod() {
Optional<MethodReader> postConstructMethod() {
return postConstructMethod;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -101,7 +102,7 @@ List<MethodReader> observerMethods() {
return extendsInjection.observerMethods();
}

Element postConstructMethod() {
Optional<MethodReader> postConstructMethod() {
return extendsInjection.postConstructMethod();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package io.avaje.inject.generator;

import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import static java.util.stream.Collectors.toList;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import static java.util.stream.Collectors.toList;

import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeKind;

final class TypeReader {

Expand Down Expand Up @@ -107,7 +107,7 @@ List<MethodReader> observerMethods() {
return extendsReader.observerMethods();
}

Element postConstructMethod() {
Optional<MethodReader> postConstructMethod() {
return extendsReader.postConstructMethod();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.avaje.inject.generator.models.valid.lifecycle;

import java.util.function.Consumer;

import io.avaje.inject.BeanScope;
import io.avaje.inject.PostConstruct;
import jakarta.inject.Singleton;

@Singleton
public class Minos {

@PostConstruct
void prepareThyself(Serpent serpent, Consumer<String> c, BeanScope b) {}

// @PreDestroy
// void thyEndIsNow() {
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.avaje.inject.generator.models.valid.lifecycle;

import java.util.function.Consumer;

import io.avaje.inject.BeanScope;
import io.avaje.inject.PostConstruct;
import io.avaje.inject.Prototype;

@Prototype
public class Serpent {

@PostConstruct
void hiss(Consumer<String> c, BeanScope b) {}

}
Loading