Hasan Can Saral
Hasan Can Saral

Reputation: 3288

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!

Upvotes: 2

Views: 10084

Answers (2)

Dirk Hoffmann
Dirk Hoffmann

Reputation: 1573

as the documentation states:

@RefreshScope works (technically) on an @Configuration class, but it might lead to surprising behaviour:
e.g. it does not mean that all the @Beans defined in that class are themselves @RefreshScope.
Specifically, anything that depends on those beans cannot rely on them being updated when a refresh is initiated,
unless it is itself in @RefreshScope (in which it will be rebuilt on a refresh and its dependencies re-injected,
at which point they will be re-initialized from the refreshed @Configuration).

So I guess you'd have to annotate a @RefreshScope also directly on the KieBase @Bean.

Upvotes: 0

spencergibb
spencergibb

Reputation: 25177

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.

Upvotes: 2

Related Questions