Search code examples
javaspringspring-bootspring-cloudspring-cloud-config

Refresh a Bean without configuration change with @RefreshScope


I have a @Configuration class as follows:

@Configuration
public class SampleKieConfiguration {

    @Bean
    public KieServices kieServices() {
        return KieServices.Factory.get();
    }

    @Bean
    public KieContainer kieContainer() {

        ReleaseId releaseId = kieServices().newReleaseId("groupId", "artifactId", "version");
        KieContainer kieContainer = kieServices().newKieContainer(releaseId);
        kieServices().newKieScanner(kieContainer).start(10_000);
        return  kieContainer;
    }

    @Bean
    public KieBase kieBase() {

        KieBaseConfiguration kieBaseConfiguration = kieServices().newKieBaseConfiguration();
        kieBaseConfiguration.setOption(EqualityBehaviorOption.EQUALITY);
        kieBaseConfiguration.setOption(EventProcessingOption.CLOUD);
        return kieContainer().newKieBase(kieBaseConfiguration);
    }
}

kieServices().newKieScanner(kieContainer).start(10_000); line basically polls a remote maven repository and refreshes the kieContainer object every 10 seconds, if there's a new artifact.

And in somewhere in my upper layers (such as services layer), I have:

@Service
@RefreshScope
public class SampleService {

    @Autowired
    private KieBase kBase;

}

The kBase object is not refreshed (at least not with the new kieContainer object) as far as I can see, when I make a call to /refresh endpoint. I don't have a centralized configuration, and I am getting a warning on it when I call /refresh. What I want to achieve is to have a new kBase object every time kieContainer is refreshed. How can I achieve this? Thanks!


Solution

  • Refresh doesn't traverse a hierarchy. It simply clears a cache and on the next reference (via the proxy it creates) the bean is recreated. In your case, since KieBase isn't @RefreshScope, it isn't recreated. So add @RefreshScope to the KieBase declaration. If SampleService doesn't really need to be recreated, remove the @RefreshScope annotation.