java - 如何在应用程序加载时加载@FeignClient

标签 java spring spring-boot netflix-feign spring-cloud-feign

我正在尝试在我的 Multi-Tenancy 应用程序中实现假客户端概念。我有两个微服务。在其中一项微服务中,我编写了 API 来从数据库获取数据。我的其他微服务中需要这些数据。为此,我使用假客户端概念。我在第二个微服务的加载期间需要数据。但这并没有发生。我收到以下错误

2018-12-14 13:03:10.555  WARN 11268 --- [  restartedMain] c.n.c.sources.URLConfigurationSource     : No URLs will be polled as dynamic configuration sources.
2018-12-14 13:03:20.468  WARN 11268 --- [  restartedMain] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'multiTenancyJpaConfiguration': Unsatisfied dependency expressed through field 'multiTenantConnectionProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
2018-12-14 13:03:21.233 DEBUG 11268 --- [  restartedMain] c.e.c.E.q.c.t.d.Project.projectRoles     : Close successful.
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'multiTenancyJpaConfiguration': Unsatisfied dependency expressed through field 'multiTenantConnectionProvider'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at com.testautomation.TestAutomationApp.main(TestAutomationApp.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSourceBasedMultiTenantConnectionProviderImpl': Invocation of init method failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:137)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 31 common frames omitted
 Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: MultiTenancyFeignClient#getDatabase(String) timed-out and no fallback available.
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:805)
at com.netflix.hystrix.AbstractCommand$22.call(AbstractCommand.java:790)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at com.netflix.hystrix.AbstractCommand$DeprecatedOnFallbackHookApplication$1.onError(AbstractCommand.java:1451)
at com.netflix.hystrix.AbstractCommand$FallbackHookApplication$1.onError(AbstractCommand.java:1376)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.observers.Subscribers$5.onError(Subscribers.java:230)
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:44)
at rx.internal.operators.OnSubscribeThrow.call(OnSubscribeThrow.java:28)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:142)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at rx.internal.operators.OnSubscribeDoOnEach$DoOnEachSubscriber.onError(OnSubscribeDoOnEach.java:87)
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$1.run(AbstractCommand.java:1121)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:41)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable$1.call(HystrixContextRunnable.java:37)
at com.netflix.hystrix.strategy.concurrency.HystrixContextRunnable.run(HystrixContextRunnable.java:57)
at com.netflix.hystrix.AbstractCommand$HystrixObservableTimeoutOperator$2.tick(AbstractCommand.java:1138)
at com.netflix.hystrix.util.HystrixTimer$1.run(HystrixTimer.java:99)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.util.concurrent.TimeoutException: null
at com.netflix.hystrix.AbstractCommand.handleTimeoutViaFallback(AbstractCommand.java:980)
at com.netflix.hystrix.AbstractCommand.access$500(AbstractCommand.java:59)
at com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:595)
at com.netflix.hystrix.AbstractCommand$12.call(AbstractCommand.java:587)
at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140)
... 15 common frames omitted

这是我的 DataSourceBasedMultiTenantConnectionProviderImpl.class,我在其中编写了假客户端逻辑

package com.testautomation.util;

import org.hibernate.engine.jdbc.connections.spi.AbstractDataSourceBasedMultiTenantConnectionProviderImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.stereotype.Component;
import com.testautomation.domain.MasterDatabase;
import com.testautomation.service.MultiTenancyFeignClient;
import com.testautomation.service.impl.ProjectServiceImpl;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {

private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1"; 
private MultiTenancyFeignClient masterTenanacyFeign;
private final Logger log = LoggerFactory.getLogger(ProjectServiceImpl.class);
public DataSourceBasedMultiTenantConnectionProviderImpl( MultiTenancyFeignClient masterTenanacyFeign) {
    this.masterTenanacyFeign = masterTenanacyFeign;

}


private Map<String, DataSource> map;


@PostConstruct
public void load() throws Exception {   
//feign client logic        
     System.out.println("Feign client logic");
     String name = "testautomation" ;
     List<MasterDatabase> result = masterTenanacyFeign.getDatabase(name);
     System.out.println("datafromUAA" +result);
//feign client logic ends

    File[] files = Paths.get("tenants").toFile().listFiles();
    Map<String, DataSource> datasources = new HashMap<>();
     for(File propertyFile : files) {
         Properties tenantProperties = new Properties();
            DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader());
            try {
                tenantProperties.load(new FileInputStream(propertyFile));
                String tenantId = tenantProperties.getProperty("name");
                 dataSourceBuilder.driverClassName("com.mysql.jdbc.Driver")
                .url(tenantProperties.getProperty("spring.datasource.url"))
                .username(tenantProperties.getProperty("spring.datasource.username"))
                .password(tenantProperties.getProperty("spring.datasource.password"));                 
                datasources.put(tenantId, dataSourceBuilder.build());                              
            } catch (IOException e) {
                e.printStackTrace();                    
            }           
     } 

    map = new HashMap<>();
        map.put("tenat3",datasources.get("tenant3"));
        map.put("tenant_1",datasources.get("tenant_1"));
       map.put("tenant_2",datasources.get("tenant_2"));
}

@Override
protected DataSource selectAnyDataSource() {
    return map.get(DEFAULT_TENANT_ID);
}

@Override
protected DataSource selectDataSource(String tenantIdentifier) {
    return map.get(tenantIdentifier);
}
}

这是 MultiTenancyFeignClient.class,我将第二个微服务连接到第一个

package com.testautomation.service;

import java.util.List;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.testautomation.domain.MasterDatabase;
import com.testautomation.util.DataSourceBasedMultiTenantConnectionProviderImpl;


@FeignClient(name="uaa" )
public interface MultiTenancyFeignClient {

 @RequestMapping(method = RequestMethod.GET, value = "/api-public/database/{name}")
    List<MasterDatabase> getDatabase(@PathVariable ("name") String name);
 }

这里有趣的事实是,如果我在应用程序启动后在 API 调用中调用我的假客户端逻辑,那么它工作得很好。但在应用程序加载期间,这种情况不会发生。

最佳答案

在 yml 页面中设置以下属性确实有效。
假装: hystrix: 启用:flase

关于java - 如何在应用程序加载时加载@FeignClient,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53775684/

相关文章:

java - Spring Boot 应用程序 : Could not resolve placeholder in application. 属性?

spring - 如何将 Spring Boot 中的 url 外部化到 application.properties 文件?

java - 3D游戏几何

java - BindingResult 和 bean 名称 '...' 的普通目标对象都不能作为请求属性

spring-data跨店实体管理

java - 将 Spring 配置文件添加到应用程序上下文

java - hibernate 不创建表但没有错误消息

JavaDoc:@链接到 MyClass.class

java - 局部变量需要声明为final

java - 列出特定深度的文件