diff --git a/spring-test/spring-test.gradle b/spring-test/spring-test.gradle
index 01edf88137..8e57b80ed9 100644
--- a/spring-test/spring-test.gradle
+++ b/spring-test/spring-test.gradle
@@ -70,6 +70,7 @@ dependencies {
testImplementation("jakarta.mail:jakarta.mail-api")
testImplementation("jakarta.validation:jakarta.validation-api")
testImplementation("javax.cache:cache-api")
+ testImplementation("javax.inject:javax.inject:1")
testImplementation("org.apache.httpcomponents:httpclient") {
exclude group: "commons-logging", module: "commons-logging"
}
diff --git a/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java
index 963c826c6d..981f0d9688 100644
--- a/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java
+++ b/spring-test/src/main/java/org/springframework/test/context/support/TestConstructorUtils.java
@@ -16,8 +16,11 @@
package org.springframework.test.context.support;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
+import java.util.LinkedHashSet;
+import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.SpringProperties;
@@ -26,6 +29,7 @@ import org.springframework.lang.Nullable;
import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.TestConstructor.AutowireMode;
import org.springframework.test.context.TestContextAnnotationUtils;
+import org.springframework.util.ClassUtils;
/**
* Utility methods for working with {@link TestConstructor @TestConstructor}.
@@ -33,6 +37,7 @@ import org.springframework.test.context.TestContextAnnotationUtils;
*
Primarily intended for use within the framework.
*
* @author Sam Brannen
+ * @author Florian Lehmann
* @since 5.2
* @see TestConstructor
*/
@@ -99,6 +104,7 @@ public abstract class TestConstructorUtils {
*
*
* - The constructor is annotated with {@link Autowired @Autowired}.
+ * - The constructor is annotated with {@link jakarta.inject.Inject} or {@code javax.inject.Inject}.
* - {@link TestConstructor @TestConstructor} is present or
* meta-present on the test class with
* {@link TestConstructor#autowireMode() autowireMode} set to
@@ -119,8 +125,8 @@ public abstract class TestConstructorUtils {
public static boolean isAutowirableConstructor(Constructor> constructor, Class> testClass,
@Nullable PropertyProvider fallbackPropertyProvider) {
- // Is the constructor annotated with @Autowired?
- if (AnnotatedElementUtils.hasAnnotation(constructor, Autowired.class)) {
+ // Is the constructor annotated with @Autowired/@Inject?
+ if (isAnnotatedWithAutowiredOrInject(constructor)) {
return true;
}
@@ -146,4 +152,30 @@ public abstract class TestConstructorUtils {
return (autowireMode == AutowireMode.ALL);
}
+ @SuppressWarnings("unchecked")
+ private static boolean isAnnotatedWithAutowiredOrInject(Constructor> constructor) {
+ Set> autowiredAnnotationTypes = new LinkedHashSet<>();
+
+ autowiredAnnotationTypes.add(Autowired.class);
+
+ try {
+ autowiredAnnotationTypes.add((Class extends Annotation>)
+ ClassUtils.forName("jakarta.inject.Inject", TestConstructorUtils.class.getClassLoader()));
+ }
+ catch (ClassNotFoundException ex) {
+ // jakarta.inject API not available - simply skip.
+ }
+
+ try {
+ autowiredAnnotationTypes.add((Class extends Annotation>)
+ ClassUtils.forName("javax.inject.Inject", TestConstructorUtils.class.getClassLoader()));
+ }
+ catch (ClassNotFoundException ex) {
+ // javax.inject API not available - simply skip.
+ }
+
+ return autowiredAnnotationTypes.stream()
+ .anyMatch(autowiredAnnotationType -> AnnotatedElementUtils.hasAnnotation(constructor, autowiredAnnotationType));
+ }
+
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/InjectAnnotationIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/InjectAnnotationIntegrationTests.java
new file mode 100644
index 0000000000..8e71198be6
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/InjectAnnotationIntegrationTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2002-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter;
+
+import org.junit.jupiter.api.Test;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Common test implementation for integration tests in order to verify support
+ * for {@link jakarta.inject.Inject} and {@link javax.inject.Inject}.
+ *
+ * @author Florian Lehmann
+ * @since 6.0.5
+ */
+@SpringJUnitConfig
+public abstract class InjectAnnotationIntegrationTests {
+
+ private final String foo;
+
+ public InjectAnnotationIntegrationTests(String foo) {
+ this.foo = foo;
+ }
+
+ @Test
+ public void beanInjected() {
+ assertThat(this.foo).isEqualTo("foo");
+ }
+
+ @Configuration
+ static class Config {
+
+ @Bean
+ String foo() {
+ return "foo";
+ }
+
+ }
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/JakartaInjectAnnotationIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/JakartaInjectAnnotationIntegrationTests.java
new file mode 100644
index 0000000000..048cfa50ad
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/JakartaInjectAnnotationIntegrationTests.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter;
+
+import jakarta.inject.Inject;
+
+/**
+ * Integration tests which verify support for {@link jakarta.inject.Inject}.
+ *
+ * @author Florian Lehmann
+ * @since 6.0.5
+ */
+@SpringJUnitConfig
+public class JakartaInjectAnnotationIntegrationTests extends InjectAnnotationIntegrationTests {
+
+ @Inject
+ public JakartaInjectAnnotationIntegrationTests(String foo) {
+ super(foo);
+ }
+
+}
diff --git a/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/JavaxInjectAnnotationIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/JavaxInjectAnnotationIntegrationTests.java
new file mode 100644
index 0000000000..1f6432eecd
--- /dev/null
+++ b/spring-test/src/test/java/org/springframework/test/context/junit/jupiter/JavaxInjectAnnotationIntegrationTests.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.test.context.junit.jupiter;
+
+import javax.inject.Inject;
+
+/**
+ * Integration tests which verify support for {@link javax.inject.Inject}.
+ *
+ * @author Florian Lehmann
+ * @since 6.0.5
+ */
+@SpringJUnitConfig
+public class JavaxInjectAnnotationIntegrationTests extends InjectAnnotationIntegrationTests {
+
+ @Inject
+ public JavaxInjectAnnotationIntegrationTests(String foo) {
+ super(foo);
+ }
+
+}