java - 不满意的依赖异常 : Error creating bean with name 'trafficMapper'

标签 java spring spring-boot reflection dependency-injection

我使用 Spring boot 应用程序并收到下面提供的错误,

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'trafficMapper': Unsatisfied dependency expressed through field 'config'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.ratepay.iris.ella.config.MasterConfig' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1378)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:846)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:88)
    at com.ratepay.iris.ella.service.EllaServiceIntegrationTest.setup(EllaServiceIntegrationTest.java:72)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:73)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.ratepay.iris.ella.config.MasterConfig' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1644)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1203)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
    ... 38 more

当我尝试进行设计集成测试的设置时发生错误。

    @Before
    @SuppressWarnings( "resource" )
    public void setup() {
        int port = wireMockRule.port();

        System.setProperty( "ella.uri", "http://localhost:" + port + ELLA_ENDPOINT );
        //        System.setProperty( "freud.master.config", "src/test/resources/test-master-config.json" );
        System.setProperty( "ella.shadowmode", "enabled" );

        ApplicationContext context = new AnnotationConfigApplicationContext( EllaConfiguration.class );
        ellaService = context.getBean( EllaService.class );
    }

这是提供错误的 LOC,

ApplicationContext context = new AnnotationConfigApplicationContext( EllaConfiguration.class );

下面提供了 EllaConfiguration 类,

@Configuration
@ComponentScan( "com.ratepay.iris.ella" )
public class EllaConfiguration {

    public static final String ELLA_CONNECTOR_BEAN_NAME = "ellaConnector";

    private static final String URI_CONFIG_KEY = "ella.uri";
    private static final String CONNECTION_TIMEOUT_CONFIG_KEY = "ella.connection_timeout";
    private static final String READ_TIMEOUT_CONFIG_KEY = "ella.read_timeout";

    private static final int DEFAULT_CONNECTION_TIMEOUT = 100;
    private static final int DEFAULT_READ_TIMEOUT = 800;

    public static final String ELLA_SHADOW_MODE_KEY = "ella.shadowmode";
    public static final String ELLA_SHADOW_MODE_ENABLED_VALUE = "enabled";

    @Bean( name = ELLA_CONNECTOR_BEAN_NAME )
    public EntityServiceConnectable<EllaResponse> timeoutConfiguration( final Environment env ) {
        return ServiceConnectorBuilder.create( createConnectionConfiguration( env ) ).timeout( createTimeoutConfiguration( env ) ).build();
    }

    private SimpleTimeoutConfiguration createTimeoutConfiguration( final Environment env ) {
        return new SimpleTimeoutConfiguration( env.getProperty( CONNECTION_TIMEOUT_CONFIG_KEY, Integer.class, DEFAULT_CONNECTION_TIMEOUT ),
                                               env.getProperty( READ_TIMEOUT_CONFIG_KEY, Integer.class, DEFAULT_READ_TIMEOUT ) );
    }

    public boolean isEllaShadowModeEnabled( final Environment env ) {
        return env.getRequiredProperty( ELLA_SHADOW_MODE_KEY ).equals( ELLA_SHADOW_MODE_ENABLED_VALUE );
    }

    private PostConnectionConfiguration<EllaResponse> createConnectionConfiguration( final Environment env ) {
        return new SimplePostConnectionConfiguration<>( env.getRequiredProperty( URI_CONFIG_KEY ), EllaResponse.class );
    }
}

提供了EllaService类,

@Service
public class EllaService {

    public static final int IRIS_ACCEPT = 0;
    public static final int IRIS_REJECT = 100;

    @Autowired
    @Qualifier( ELLA_CONNECTOR_BEAN_NAME )
    private EntityServiceConnectable<EllaResponse> connector;

    @Autowired
    private TrafficMapper trafficMapper;

    @Autowired
    private EllaConfiguration config;

    @Autowired
    private Environment env;

    @Getter
    private boolean shadowModeEnabled = false;

    /**
     * Initialize the service.
     */
    @PostConstruct
    public void initialize() {
        this.shadowModeEnabled = config.isEllaShadowModeEnabled( env );
    }

    /**
     * Asynchronously call Ella. Determine if traffic is applicable for Ella and if yes forward to Ella.
     *
     * @param irisEo
     * @return List<ResultBo>
     * @throws EllaGatewayUnsuccessfulResponseException
     */
    @Async
    public void invokeEllaAsync( final IrisEo irisEo ) throws EllaGatewayUnsuccessfulResponseException {
        invokeEllaSync( irisEo );
    }

    /**
     * Synchronously call Ella. Determine if traffic is applicable for Ella and if yes forward to Ella.
     *
     * @param irisEo
     * @return List<ResultBo>
     * @throws EllaGatewayUnsuccessfulResponseException
     */
    public List<ResultBo> invokeEllaSync( final IrisEo irisEo ) throws EllaGatewayUnsuccessfulResponseException {

        Optional<String> mapId = trafficMapper.getApplicableMapId( irisEo );

        if( mapId.isPresent() && StringUtils.isNotEmpty( mapId.get() ) ) {

            try {
                return irisEo.getOrder().getProducts().stream().map( product -> fetchEllaResult( irisEo, mapId.get(), product ) )
                        .collect( Collectors.toList() );
            }
            catch( EllaGatewayUnsuccessfulResponseException ex ) {
                throw new EllaGatewayUnsuccessfulResponseException( ex.getMessage(), ex.getCause() );
            }
        }
        return Collections.emptyList();
    }

    private ResultBo fetchEllaResult( final IrisEo irisEo, String mapId, String product ) throws EllaGatewayUnsuccessfulResponseException {

        HttpHeaders freudHeaders = createRequestHeaders( irisEo );

        ServiceResponse<EllaResponse> response = connector
                .call( EllaDtoConverter.convertToRequest( irisEo, mapId, product ), freudHeaders );

        if( !response.isSuccess() ) {
            throw new EllaGatewayUnsuccessfulResponseException( response.getErrorMessage(), response.getException().getCause() );
        }

        EllaResult prediction = response.getResponse().getResult();

        return convertToResultBo( prediction, product );

    }

    private ResultBo convertToResultBo( EllaResult prediction, String product ) {

        ClassificationResult classification = prediction.getClassification();
        final int irisPrediction = ClassificationResult.FRAUD.equals( classification ) ? IRIS_REJECT : IRIS_ACCEPT;
        //        final int irisPrediction = Integer.valueOf( classification.getValue() ) < 900 ? IRIS_REJECT : IRIS_ACCEPT;

        return new ResultBo( product, irisPrediction );
    }

    private HttpHeaders createRequestHeaders( final IrisEo irisEo ) {

        HttpHeaders freudHeaders = new HttpHeaders();

        freudHeaders.add( ACCEPT, APPLICATION_JSON_UTF8_VALUE );
        RatepayHeaders.append( freudHeaders, irisEo.getRequestInfo() );

        return freudHeaders;
    }

}

我从 LOC 中的 invokeEllaSync 方法获得 NPE,

Optional<String> mapId = trafficMapper.getApplicableMapId( irisEo );

提供了TrafficMapper类,

@Component
public class TrafficMapper {

    @Autowired
    private MasterConfig config;

    private final Map<Integer, String> shopIdToMapId = new HashMap<>();

    /**
     * Initialize the component.
     */
    @PostConstruct
    public void initialize() {
        fillShopIdMap();
    }

    /**
     * Return an optional holding a specific map id.
     *
     * @param irisEo
     * @return Optional<String>
     */
    public Optional<String> getApplicableMapId( IrisEo irisEo ) {

        Integer shopId = irisEo.getOrder().getShopId();
        return Optional.ofNullable( this.shopIdToMapId.get( shopId ) );
    }

    private void fillShopIdMap() {

        this.config.getTrafficMappings().stream().forEach( trafficMapping -> trafficMapping.getTrafficDescription().getShopIds().stream()
                .forEach( shopId -> this.shopIdToMapId.put( shopId, trafficMapping.getMapId() ) ) );
    }
}

提供了MasterConfig类,

@Getter
@Setter
@ToString
public class MasterConfig {

    @NotNull
    @JsonProperty( "traffic_mappings" )
    private List<TrafficMapping> trafficMappings;
}

我提供类(class)的原因是我无法找到问题并希望提供更多信息以供调查。

如何解决 UnsatisfiedDependencyException 错误?

PS:

如果不合适我可以修改问题。如果您有合理的疑虑,请在下面发表评论。

最佳答案

MasterConfig类添加Component注释。

@Component
@Getter
@Setter
@ToString
public class MasterConfig {

    @NotNull
    @JsonProperty( "traffic_mappings" )
    private List<TrafficMapping> trafficMappings;
}

Autowired 表示您想要将 Bean 注入(inject)到字段等
所以 MasterConfig 应该是一个 bean。您可以将其设为组件、服务或其他 bean。

关于java - 不满意的依赖异常 : Error creating bean with name 'trafficMapper' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56364258/

相关文章:

java - 使用java拆分xml文件

spring mvc i18n : If key not in properties file, 如何设置默认语言环境?

java - 在浏览器上呈现 .csv 文件而不是下载

java - 如何使用 rest-assured 将 header 位置响应与正则表达式匹配

java - 有没有办法多次迭代 HttpServletRequest.getAttributeNames() ?

java - Spring Security 超时时将用户重定向到登录页面

java - Spring 3 注入(inject) Hibernate Session 的最佳方法

java - 干净的代码 - 应该在哪里应用 @Autowired?

java - 如何在对象的数组属性中添加 Rest 验证?

javascript - 如何构建一个每天调用另一个javascript文件的Java文件?