Polishing
This commit is contained in:
@@ -34,8 +34,8 @@ dependencies {
|
||||
testCompile("org.codehaus.groovy:groovy-test")
|
||||
testCompile("org.codehaus.groovy:groovy-xml")
|
||||
testCompile("org.apache.commons:commons-pool2")
|
||||
testCompile("javax.inject:javax.inject-tck")
|
||||
testCompile("org.awaitility:awaitility")
|
||||
testCompile("javax.inject:javax.inject-tck")
|
||||
testRuntime("javax.xml.bind:jaxb-api")
|
||||
testRuntime("org.glassfish:javax.el")
|
||||
// Substitute for javax.management:jmxremote_optional:1.0.1_04 (not available on Maven Central)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -25,7 +25,6 @@ import org.springframework.beans.testfixture.beans.TestBean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
/**
|
||||
* Tests cornering the issue reported in SPR-8080. If the product of a @Bean method
|
||||
* was @Autowired into a configuration class while at the same time the declaring
|
||||
@@ -34,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* 'currently in creation' status of the autowired bean and result in creating multiple
|
||||
* instances of the given @Bean, violating container scoping / singleton semantics.
|
||||
*
|
||||
* This is resolved through no longer relying on 'currently in creation' status, but
|
||||
* <p>This is resolved through no longer relying on 'currently in creation' status, but
|
||||
* rather on a thread local that informs the enhanced bean method implementation whether
|
||||
* the factory is the caller or not.
|
||||
*
|
||||
|
||||
@@ -53,22 +53,22 @@ dependencies {
|
||||
optional("io.reactivex:rxjava-reactive-streams")
|
||||
optional("io.reactivex.rxjava2:rxjava")
|
||||
optional("io.netty:netty-buffer")
|
||||
testCompile("io.projectreactor:reactor-test")
|
||||
testCompile("com.google.code.findbugs:jsr305")
|
||||
testCompile(project(":kotlin-coroutines"))
|
||||
testCompile("javax.annotation:javax.annotation-api")
|
||||
testCompile("javax.xml.bind:jaxb-api")
|
||||
testCompile("com.google.code.findbugs:jsr305")
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core")
|
||||
testCompile("org.xmlunit:xmlunit-assertj")
|
||||
testCompile("org.xmlunit:xmlunit-matchers")
|
||||
testCompile(project(":kotlin-coroutines"))
|
||||
testCompile("io.projectreactor:reactor-test")
|
||||
testCompile("io.projectreactor.tools:blockhound")
|
||||
testFixturesImplementation("io.projectreactor:reactor-test")
|
||||
testFixturesImplementation("com.google.code.findbugs:jsr305")
|
||||
testFixturesImplementation("org.junit.platform:junit-platform-launcher")
|
||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
testFixturesImplementation("org.junit.jupiter:junit-jupiter-params")
|
||||
testFixturesImplementation("org.assertj:assertj-core")
|
||||
testFixturesImplementation("org.xmlunit:xmlunit-assertj")
|
||||
testFixturesImplementation("io.projectreactor:reactor-test")
|
||||
}
|
||||
|
||||
jar {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
* Copyright 2002-2021 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.
|
||||
@@ -47,7 +47,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
*
|
||||
* <p>By default, depending on classpath availability, adapters are registered
|
||||
* for Reactor, RxJava 1, RxJava 2 types, {@link CompletableFuture}, Java 9+
|
||||
* {@code Flow.Publisher} and Kotlin Coroutines {@code Deferred} and {@code Flow}.
|
||||
* {@code Flow.Publisher}, and Kotlin Coroutines {@code Deferred} and {@code Flow}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
@@ -74,6 +74,10 @@ public class ReactiveAdapterRegistry {
|
||||
boolean reactorRegistered = false;
|
||||
if (ClassUtils.isPresent("reactor.core.publisher.Flux", classLoader)) {
|
||||
new ReactorRegistrar().registerAdapters(this);
|
||||
if (ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader)) {
|
||||
// Java 9+ Flow.Publisher
|
||||
new ReactorJdkFlowAdapterRegistrar().registerAdapter(this);
|
||||
}
|
||||
reactorRegistered = true;
|
||||
}
|
||||
this.reactorPresent = reactorRegistered;
|
||||
@@ -83,20 +87,12 @@ public class ReactiveAdapterRegistry {
|
||||
ClassUtils.isPresent("rx.RxReactiveStreams", classLoader)) {
|
||||
new RxJava1Registrar().registerAdapters(this);
|
||||
}
|
||||
|
||||
// RxJava2
|
||||
if (ClassUtils.isPresent("io.reactivex.Flowable", classLoader)) {
|
||||
new RxJava2Registrar().registerAdapters(this);
|
||||
}
|
||||
|
||||
// Java 9+ Flow.Publisher
|
||||
if (ClassUtils.isPresent("java.util.concurrent.Flow.Publisher", classLoader)) {
|
||||
new ReactorJdkFlowAdapterRegistrar().registerAdapter(this);
|
||||
}
|
||||
// If not present, do nothing for the time being...
|
||||
// We can fall back on "reactive-streams-flow-bridge" (once released)
|
||||
|
||||
// Coroutines
|
||||
// Kotlin Coroutines
|
||||
if (this.reactorPresent && ClassUtils.isPresent("kotlinx.coroutines.reactor.MonoKt", classLoader)) {
|
||||
new CoroutinesRegistrar().registerAdapters(this);
|
||||
}
|
||||
@@ -226,6 +222,35 @@ public class ReactiveAdapterRegistry {
|
||||
}
|
||||
|
||||
|
||||
private static class ReactorJdkFlowAdapterRegistrar {
|
||||
|
||||
void registerAdapter(ReactiveAdapterRegistry registry) {
|
||||
// Reflectively access optional JDK 9+ API (for runtime compatibility with JDK 8)
|
||||
|
||||
try {
|
||||
String publisherName = "java.util.concurrent.Flow.Publisher";
|
||||
Class<?> publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader());
|
||||
|
||||
String adapterName = "reactor.adapter.JdkFlowAdapter";
|
||||
Class<?> flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader());
|
||||
|
||||
Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass);
|
||||
Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class);
|
||||
Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty());
|
||||
|
||||
registry.registerReactiveType(
|
||||
ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow),
|
||||
source -> (Publisher<?>) ReflectionUtils.invokeMethod(toFluxMethod, null, source),
|
||||
publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher)
|
||||
);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class RxJava1Registrar {
|
||||
|
||||
void registerAdapters(ReactiveAdapterRegistry registry) {
|
||||
@@ -280,35 +305,6 @@ public class ReactiveAdapterRegistry {
|
||||
}
|
||||
|
||||
|
||||
private static class ReactorJdkFlowAdapterRegistrar {
|
||||
|
||||
void registerAdapter(ReactiveAdapterRegistry registry) {
|
||||
// TODO: remove reflection when build requires JDK 9+
|
||||
|
||||
try {
|
||||
String publisherName = "java.util.concurrent.Flow.Publisher";
|
||||
Class<?> publisherClass = ClassUtils.forName(publisherName, getClass().getClassLoader());
|
||||
|
||||
String adapterName = "reactor.adapter.JdkFlowAdapter";
|
||||
Class<?> flowAdapterClass = ClassUtils.forName(adapterName, getClass().getClassLoader());
|
||||
|
||||
Method toFluxMethod = flowAdapterClass.getMethod("flowPublisherToFlux", publisherClass);
|
||||
Method toFlowMethod = flowAdapterClass.getMethod("publisherToFlowPublisher", Publisher.class);
|
||||
Object emptyFlow = ReflectionUtils.invokeMethod(toFlowMethod, null, Flux.empty());
|
||||
|
||||
registry.registerReactiveType(
|
||||
ReactiveTypeDescriptor.multiValue(publisherClass, () -> emptyFlow),
|
||||
source -> (Publisher<?>) ReflectionUtils.invokeMethod(toFluxMethod, null, source),
|
||||
publisher -> ReflectionUtils.invokeMethod(toFlowMethod, null, publisher)
|
||||
);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ReactiveAdapter variant that wraps adapted Publishers as {@link Flux} or
|
||||
* {@link Mono} depending on {@link ReactiveTypeDescriptor#isMultiValue()}.
|
||||
|
||||
Reference in New Issue
Block a user