Неразрешимая циклическая ссылка с @RefreshScope на @Configuration или @SpringBootApplication

Я пытаюсь получить обновленное значение своего свойства apiKey после его изменения и запроса конечной точки /refresh.

По какой-то причине мой компонент не может получить обновленное значение даже при аннотации @RefreshScope. Я добавил @RefreshScope в свой класс, как и в свой DatasourceConfig, но в этом случае я получаю такую ​​ошибку:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.application': Initialization of bean failed;

nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.application.initTimestamp.transformer.handler': Invocation of init method failed;

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'scopedTarget.application': Requested bean is currently in creation: Is there an unresolvable circular reference?

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  scopedTarget.application
└─────┘

Вот мой Application.java:

@SpringBootApplication
@EnableConfigServer
@EnableSwagger2
@RefreshScope
public class Application{

    @Value("${api.key}")
    private String apiKey;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Autowired
    private IMonitoringsService monitoringsService;

    @Bean
    public MessageChannel initTimestampChannel() {
        return new DirectChannel();
    }

    @RefreshScope
    @Bean
    @InboundChannelAdapter(value = "initTimestampChannel", poller = @Poller(fixedRate = "${start.task.rate}"))
    public MessageSource<?> buildRequestMessageSource() {
        MethodInvokingMessageSource source = new MethodInvokingMessageSource();
        source.setObject(tasksService);
        source.setMethodName("requestAllTasks");
        System.out.println(apiKey);
        return source;
    }

}

Тем не менее, это работает для моего DatasourceConfig:

@RefreshScope
@Configuration
public class DatasourceConfig {
    @Value("${spring.datasource.tomcat.max-active}")
    private int maxActive;

    @RefreshScope
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource dataSource() {
        DataSource dataSource = DataSourceBuilder.create().build();
        org.apache.tomcat.jdbc.pool.DataSource ds = (org.apache.tomcat.jdbc.pool.DataSource) dataSource;
        ds.setMaxActive(maxActive);
        return ds;
    }
}

Я использую :

<spring-cloud.version>Edgware.SR2</spring-cloud.version>
<spring-boot-version>1.5.9.RELEASE</spring-boot-version>

Вы не должны помещать @RefreshScope в классы @Configuration. Какие версии boot и cloud вы используете?

spencergibb 19.08.2018 20:01

Я обновил свой пост. Значит ли это, что единственное решение - использовать @ConfigurationProperties?

redAce 19.08.2018 20:18

Нет, вы также можете передать Spring Environment в dataSource().

spencergibb 20.08.2018 17:07
0
3
326
1

Ответы 1

Как предложил spencergibb, вам не следует помещать @SpringBootApplication и @RefreshScope в один и тот же класс. Удалите @RefreshScope из Application и переместите конфигурацию, для которой требуется @RefreshScope, в отдельный класс.

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