简体   繁体   English

Spring 引导找不到我的 Java bean 映射器

[英]Spring Boot doesn't find my Java bean mapper

I'm getting an error when I try to start Spring Boot using a Java bean mapper.当我尝试使用 Java bean 映射器启动 Spring Boot 时出现错误。 I'm using Eclipse on Windows, Gradle to build.我在 Windows、Gradle 上使用 Eclipse 进行构建。 This is just a learning project I'm using to learn these components.这只是我用来学习这些组件的一个学习项目。

I'm listening to an ActiveMQ Artemis queue, using the incoming data to call a web service, then saving the order response in a MondoDB.我正在监听 ActiveMQ Artemis 队列,使用传入数据调用 web 服务,然后将订单响应保存在 MondoDB 中。 All the components are working with the exception of the mapper converting the api response to a MongoDB entity.除了将 api 响应转换为 MongoDB 实体的映射器之外,所有组件都在工作。

Can anyone see what I'm doing wrong here?谁能看到我在这里做错了什么? It's something with how I'm injecting the OrderMapper, but I'm not sure at this point.这与我注入 OrderMapper 的方式有关,但目前我不确定。 This is the Spring output:这是 Spring output:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.5)

2021-04-30 14:16:15.860  INFO 2320 --- [           main] c.b.R.RestClientPocApplication           : Starting RestClientPocApplication using Java 11.0.9 on PSPLT-F7VYYY2 with PID 2320 (C:\Users\Bwarrick\Workspaces\Java\RESTClientPOC\bin\main started by Bwarrick in C:\Users\Bwarrick\Workspaces\Java\RESTClientPOC)
2021-04-30 14:16:15.863  INFO 2320 --- [           main] c.b.R.RestClientPocApplication           : No active profile set, falling back to default profiles: default
2021-04-30 14:16:16.405  INFO 2320 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
2021-04-30 14:16:16.567  INFO 2320 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 157 ms. Found 1 MongoDB repository interfaces.
2021-04-30 14:16:16.991  INFO 2320 --- [           main] org.mongodb.driver.cluster               : Cluster created with settings {hosts=[192.168.56.102:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms'}
2021-04-30 14:16:17.064  INFO 2320 --- [68.56.102:27017] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:1, serverValue:49}] to 192.168.56.102:27017
2021-04-30 14:16:17.064  INFO 2320 --- [68.56.102:27017] org.mongodb.driver.connection            : Opened connection [connectionId{localValue:2, serverValue:50}] to 192.168.56.102:27017
2021-04-30 14:16:17.065  INFO 2320 --- [68.56.102:27017] org.mongodb.driver.cluster               : Monitor thread successfully connected to server with description ServerDescription{address=192.168.56.102:27017, type=STANDALONE, state=CONNECTED, ok=true, minWireVersion=0, maxWireVersion=9, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=23420200}
2021-04-30 14:16:17.332  WARN 2320 --- [           main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'artemisConsumer' defined in file [C:\Users\Bwarrick\Workspaces\Java\RESTClientPOC\bin\main\com\benwarrick\RESTClientPOC\jms\ArtemisConsumer.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.benwarrick.RESTClientPOC.service.OrderMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2021-04-30 14:16:17.355  INFO 2320 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-04-30 14:16:17.370 ERROR 2320 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 1 of constructor in com.benwarrick.RESTClientPOC.jms.ArtemisConsumer required a bean of type 'com.benwarrick.RESTClientPOC.service.OrderMapper' that could not be found.


Action:

Consider defining a bean of type 'com.benwarrick.RESTClientPOC.service.OrderMapper' in your configuration.

Here is my component:这是我的组件:

package com.benwarrick.RESTClientPOC.jms;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
    
    import com.benwarrick.RESTClientPOC.persistance.OrderEntity;
    import com.benwarrick.RESTClientPOC.persistance.OrderRepository;
    import com.benwarrick.RESTClientPOC.service.CoinBaseClientServiceImpl;
    import com.benwarrick.RESTClientPOC.service.OrderMapper;
    import com.benwarrick.RESTClientPOC.service.OrderResponse;
    import com.benwarrick.RESTClientPOC.service.Price;
    import com.benwarrick.RESTClientPOC.service.Prices;
    import reactor.core.publisher.Mono;
    import reactor.core.publisher.Flux;
    
    @Component
    public class ArtemisConsumer {
    
        private final OrderRepository orderRepository; 
        private final OrderMapper orderMapper;
        
        @Autowired
        public ArtemisConsumer(OrderRepository orderRepository, OrderMapper orderMapper) {
            this.orderRepository = orderRepository; 
            this.orderMapper = orderMapper; 
        }
        
        
        @JmsListener(destination = "test.topic::test.queue")
        public void receive(String msg){
            System.out.println("Got Message: " + msg);
            
            CoinBaseClientServiceImpl client = new CoinBaseClientServiceImpl();
            
            Mono<OrderResponse>orderCreate = client.createOrder("market", "USD", "BTC", "5");
            orderCreate.log().subscribe(
                    successValue -> processResponse(successValue),
                    error -> System.err.println(error.getMessage()),
                    () -> System.out.println("mono consumed")
                    );
        }
        
        public void processResponse(OrderResponse orderResponse) {
            
            System.out.println(orderResponse.getOrderID() + " " + orderResponse.getSellingCurrency() + orderResponse.getBuyingCurrency() + " Qty: " 
                    + orderResponse.getBoughtQty() + " Type: " + orderResponse.getOrderType()) ;
            try {
            OrderEntity entity = orderMapper.apiResponseToEntity(orderResponse); 
            OrderEntity newEntity = orderRepository.save(entity); 
            System.out.println("Test: " + newEntity.getBoughtQuantity()); 
            }
            catch(Exception e) {
                System.out.println("Exception: " + e.toString()) ;
            }
        }
    }

Here is my main process:这是我的主要过程:

package com.benwarrick.RESTClientPOC;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class RestClientPocApplication {
    private static final Logger LOG = LoggerFactory.getLogger(RestClientPocApplication.class);

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = 
        SpringApplication.run(RestClientPocApplication.class, args);
        String mongoDBHost = ctx.getEnvironment().getProperty("spring.data.mongodb.host");
        String mongoDbPort = ctx.getEnvironment().getProperty("spring.data.mongodb.port");
        LOG.info("Connected to MongoDb: " + mongoDBHost + ":" + mongoDbPort); 
    }

}

And here is the bean that isn't being found:这是找不到的bean:

package com.benwarrick.RESTClientPOC.service;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;

import com.benwarrick.RESTClientPOC.persistance.OrderEntity;

@Mapper (componentModel = "spring")
public interface OrderMapper {
    
    @Mappings({
        @Mapping(target = "id", ignore = true),
        @Mapping(target = "version", ignore = true),
        @Mapping(target = "orderId", source="orderID"),
        @Mapping(target = "orderID", source="boughtQty")
    })
    OrderEntity apiResponseToEntity(OrderResponse api); 
}

And my build.graddle还有我的 build.graddle

plugins {
    id 'org.springframework.boot' version '2.4.5'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.benwarrick'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

ext {
    mapstructVersion = "1.4.2.Final"
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-artemis'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'io.projectreactor:reactor-test'
    
    implementation("org.mapstruct:mapstruct:${mapstructVersion}")
    compileOnly "org.mapstruct:mapstruct-processor:${mapstructVersion}"
    annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
    testAnnotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"
    
    implementation('org.springframework.boot:spring-boot-starter-data-mongodb')
    testImplementation('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
}

test {
    useJUnitPlatform()
}

For MapStruct you need to correctly set up annotation processor so that IDE (Eclipse in your case) and build tool, Gradle that is play well together.对于 MapStruct,您需要正确设置注释处理器,以便 IDE(在您的情况下为 Eclipse)和构建工具 Gradle 可以很好地配合使用。

You can read on MapStruct page uder IDE support about it.您可以在MapStruct 页面上阅读有关它的 IDE 支持 Now I didn't manage to get it working without issues that way.现在我没有设法让它没有问题地工作。

Plugin to the rescue.插件来救援。 Now what I recommend you is that you use following Gradle plugin that can set up Eclipse IDE in a proper way for you: The plugin: https://plugins.gradle.org/plugin/com.diffplug.eclipse.apt Now what I recommend you is that you use following Gradle plugin that can set up Eclipse IDE in a proper way for you: The plugin: https://plugins.gradle.org/plugin/com.diffplug.eclipse.apt

I see you know already how to include the plugin, just in case the code that you have to add to build.gradle:我看到您已经知道如何包含该插件,以防您必须添加到 build.gradle 的代码:

plugins {
    ...
    id 'com.diffplug.eclipse.apt' version "3.29.1"
}

And then run the command from your project that will set up Eclipse:然后从您的项目中运行将设置 Eclipse 的命令:

./gradlew eclipseJdtApt eclipseFactorypath eclipseJdt

From within Eclipse, you now have to run right-click the project and select Gradle / Refresh Gradle Project.在 Eclipse 中,您现在必须运行右键单击该项目和 select Gradle / 刷新 Z7B5CC4FB56E11DC1EC7520 项目。

在此处输入图像描述

Afterwards, Project / Clean.之后,项目/清理。 With this clean build, the annotation-processor should be running.有了这个干净的构建,注释处理器应该正在运行。

I hope Eclipse Buildship will pick this up and make it easier to support his feature.我希望 Eclipse Buildship 能够接受这一点,并使其更容易支持他的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM