Использование Spring MVC с Spring WebFlux без использования Spring Boot

Итак, у меня есть старое рабочее приложение, которое использует Spring MVC, а не весеннюю загрузку. Я добавил в свой проект градуированную зависимость от spring-webflux и начал использовать веб-клиент для вызова внешних API из моего проекта. Это мой класс обработчика веб-клиента:

@Service
public class WebclientHandler {
    private final WebClient webClient;

    public WebclientHandler (WebClient.Builder builder) {
        this.webClient = builder.baseUrl("baseurl").build();
    }
}

Теперь я получаю эту ошибку после того, как я вызываю этот код через свой API:

Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.web.reactive.function.client.WebClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

Похоже, что мое приложение не может найти Webclient.builder, и внедрение конструктора не происходит. Это потому, что я не использую весеннюю загрузку?

Это моя зависимость Gradle:

compile(group: 'org.springframework', name: 'spring-webflux', version: '5.3.15')

Я новичок в реактивном программировании spring-webflux.

РЕДАКТИРОВАТЬ

Я также попытался создать компонент Webclient, используя конфигурацию:

 @Configuration
    public class WebClientHandler {
    
    @Bean
        public WebClient myWebClient() {
            WebClient client = WebClient.builder().baseUrl("baseUrl")
                    .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                    .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
                    .build();
            return client;
        }
}

Теперь я получаю это исключение при запуске:

{ java.lang.IllegalStateException: No suitable default ClientHttpConnector found
    at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.initConnector(DefaultWebClientBuilder.java:297)
    at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.build(DefaultWebClientBuilder.java:266)
    at com.kronos.orgmap.sbs.impl.service.WebClientHandler.MyWebClient(WebClientHandler.java:41)
    at com.kronos.orgmap.sbs.impl.service.WebClientHandler$$EnhancerBySpringCGLIB$$59a9a582.CGLIB$desiWebClient$0(<generated>)
    at com.kronos.orgmap.sbs.impl.service.WebClientHandler$$EnhancerBySpringCGLIB$$59a9a582$$FastClassBySpringCGLIB$$76fa510d.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
    at com.kronos.orgmap.sbs.impl.service.WebClientHandler$$EnhancerBySpringCGLIB$$59a9a582.MyWebClient(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    at org.springframework.beans.factory.support.KronosConstructorResolver.instantiate(KronosConstructorResolver.java:654)
    at org.springframework.beans.factory.support.KronosConstructorResolver.instantiateUsingFactoryMethod(KronosConstructorResolver.java:487)
    at org.springframework.beans.factory.support.KronosAbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(KronosAbstractAutowireCapableBeanFactory.java:1345)
    at org.springframework.beans.factory.support.KronosAbstractAutowireCapableBeanFactory.createBeanInstance(KronosAbstractAutowireCapableBeanFactory.java:1193)
    at org.springframework.beans.factory.support.KronosAbstractAutowireCapableBeanFactory.doCreateBean(KronosAbstractAutowireCapableBeanFactory.java:611)
    at org.springframework.beans.factory.support.KronosAbstractAutowireCapableBeanFactory.createBean(KronosAbstractAutowireCapableBeanFactory.java:559)
    at org.springframework.beans.factory.support.KronosAbstractBeanFactory.lambda$doGetBean$0(KronosAbstractBeanFactory.java:336)
    at org.springframework.beans.factory.support.KronosDefaultSingletonBeanRegistry.getSingleton(KronosDefaultSingletonBeanRegistry.java:235)
    at org.springframework.beans.factory.support.KronosAbstractBeanFactory.doGetBean(KronosAbstractBeanFactory.java:334)
    at org.springframework.beans.factory.support.KronosAbstractBeanFactory.getBean(KronosAbstractBeanFactory.java:209)
    at org.springframework.beans.factory.support.KronosDefaultListableBeanFactory.preInstantiateSingletons(KronosDefaultListableBeanFactory.java:952)
    at com.kronos.container.impl.startup.KronosBeanFactory.preInstantiateSingletons(KronosBeanFactory.java:226)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4699)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5167)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
    at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1125)
    at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1859)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
 } }
0
0
48
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Добавление этих зависимостей в мою градацию решило проблему для меня для второго подхода. Теперь DefaultWebClientBuilder может инициировать соединитель, который будет использоваться построителем веб-клиента.

implementation platform('io.projectreactor:reactor-bom:2020.0.17')
    implementation 'io.projectreactor.netty:reactor-netty-core' 
    implementation 'io.projectreactor.netty:reactor-netty-http'

Хотя до сих пор не понял, почему первый подход не работает даже после добавления упомянутых зависимостей gradle. Все еще не удается найти класс WebClient.Builder как bean-компонент в конструкторе.

Другие вопросы по теме