使用 Spring mvc 和 spring webflux 而不使用 spring boot

发布于 2025-01-15 00:48:41 字数 6253 浏览 1 评论 0原文

所以我有一个旧的工作应用程序,它使用 Spring MVC 而不是 spring boot。我在我的项目中添加了 spring-webflux 的 gradle 依赖项,并开始使用 webclient 从我的项目中调用外部 API。这是我的 webclient 处理程序类:

@Service
public class WebclientHandler {
    private final WebClient webClient;

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

现在,当我通过 API 调用此代码后,我收到此错误:

通过构造函数参数 0 表达的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有类型为“org.springframework.web.reactive.function.client.WebClient$Builder”的合格 bean 可用:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖项注释:{}

似乎我的应用程序无法找到 Webclient.builder 并且不会发生构造函数注入。这是因为我没有使用 spring boot 吗?

这是我的 Gradle 依赖项:

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

我是 spring-webflux 反应式编程的新手。

编辑

我也尝试使用配置创建 Webclient bean:

 @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)
 } }

So I have a old working application which uses Spring MVC and not spring boot. I have added gradle dependency of spring-webflux in my project and start using webclient for calling external APIs from my project. This is my webclient handler class:

@Service
public class WebclientHandler {
    private final WebClient webClient;

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

Now I am getting this error after when I call this code through my 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: {}

It seems like my application is not able to find Webclient.builder and constructor injection does not occur. Is this because I am not using spring boot?

This is my Gradle dependency:

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

I am new to spring-webflux reactive programming.

EDIT

I have tried to create Webclient bean using configuration also:

 @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;
        }
}

Now I am getting this exception on startup:

{ 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)
 } }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

跨年 2025-01-22 00:48:41

在我的 gradle 中添加这些依赖项为我解决了第二种方法的问题,现在 DefaultWebClientBuilder 能够启动由 webclient 构建器使用的连接器。

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。

Adding these dependencies in my gradle resolved the issue for me for 2nd approach, Now the DefaultWebClientBuilder is able to initiate connector to be used by webclient builder.

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

Although still didn't figured out why the first approach not working even after adding the mentioned gradle dependencies. Still not able to find WebClient.Builder class as bean in constructor.

近箐 2025-01-22 00:48:41

您只能使用“spring-boot-starter-webflux”:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>2.7.4</version>
</dependency>

You can only use 'spring-boot-starter-webflux':

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>2.7.4</version>
</dependency>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文