Search code examples
javaspringconsulmicronaut

How do I access the ApplicationContext from a service within the micronaut framework?


Every attempt I have made to access the ApplicationContext in my service has failed with the ApplicationContext being returned as null. In Spring I was able to use ApplicationContextAware which according to (https://micronaut-projects.github.io/micronaut-spring/latest/guide/index.html) should be replaced with @Autowired in micronaut. I have attempted

@Autowired ApplicationContext context

with no luck however. It is always null. Any help would be appreciated!


Solution

  • The project at https://github.com/jeffbrown/injectcontext shows 2 ways to inject the ApplicationContext.

    https://github.com/jeffbrown/injectcontext/blob/1f319a3bb3db8eff05f159dd8dc642b227662307/src/main/java/injectcontext/FirstService.java

    package injectcontext;
    
    import io.micronaut.context.ApplicationContext;
    
    import javax.inject.Singleton;
    
    @Singleton
    public class FirstService {
    
        private final ApplicationContext applicationContext;
    
        public FirstService(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }
    
        public boolean isContextNull() {
            return applicationContext == null;
        }
    }
    

    https://github.com/jeffbrown/injectcontext/blob/1f319a3bb3db8eff05f159dd8dc642b227662307/src/main/java/injectcontext/SecondService.java

    package injectcontext;
    
    import io.micronaut.context.ApplicationContext;
    
    import javax.inject.Inject;
    import javax.inject.Singleton;
    
    @Singleton
    public class SecondService {
    
        @Inject
        ApplicationContext applicationContext;
    
        public boolean isContextNull() {
            return applicationContext == null;
        }
    }
    

    https://github.com/jeffbrown/injectcontext/blob/1f319a3bb3db8eff05f159dd8dc642b227662307/src/main/java/injectcontext/DemoController.java

    package injectcontext;
    
    import io.micronaut.http.annotation.Controller;
    import io.micronaut.http.annotation.Get;
    
    @Controller("/")
    public class DemoController {
    
        FirstService firstService;
    
        SecondService secondService;
    
        public DemoController(FirstService firstService, SecondService secondService) {
            this.firstService = firstService;
            this.secondService = secondService;
        }
    
        @Get("/first")
        public String first() {
            boolean isNull = firstService.isContextNull();
    
            return "firstService.isContextNull() == " + isNull;
        }
    
        @Get("/second")
        public String second() {
            boolean isNull = secondService.isContextNull();
    
            return "secondService.isContextNull() == " + isNull;
        }
    }
    

    That all works:

     $ curl http://localhost:8080/first
    firstService.isContextNull() == false
     $ 
     $ curl http://localhost:8080/second
    secondService.isContextNull() == false
    

    EDIT

    If what you really want is to just retrieve the service ids, you can do something like this:

    package injectcontext;
    
    import io.micronaut.discovery.DiscoveryClient;
    import org.reactivestreams.Publisher;
    
    import javax.inject.Singleton;
    import java.util.List;
    
    @Singleton
    public class DiscoveryHelper {
    
        private final DiscoveryClient consulClient;
    
        public DiscoveryHelper(DiscoveryClient consulClient) {
            this.consulClient = consulClient;
        }
    
        public Publisher<List<String>> getIds() {
            // do whatever you want with the ids...
            return consulClient.getServiceIds();
        }
    }
    

    That will work if you have that in a service that has consul enabled.

    consul:
      client:
        registration:
          enabled: false # set to true if you want this service to register itself
        defaultZone: "${CONSUL_HOST:localhost}:${CONSUL_PORT:8500}"