Search code examples
micronaut

How do I inject static resources dynamically rather than declaring in central application.yml


I have a micronaut web service built from separate libraries. 2 of these libraries have static resources, and I would like each library to declare it's own static resources.

  • service depends on lib1.jar and lib2.jar
  • lib1.jar contains
    • code
    • static/lib1/files
  • lib2.jar contains
    • code
    • static/lib2/files

I want the following static declarations, but I would like each declaration to be added dynamically if the library is used, so ideally the libraries add their own static resources

micronaut:
  router:
    static-resources:
      lib1:
        mapping: /lib1/**
        paths:
          - classpath:static/lib1
      lib2:
        mapping: /lib2/**
        paths:
          - classpath:static/lib2

I have tried to put an application.yml file in each library but micronaut does not seem to look for all such files and stops at the first one found.

So far I got this to work in 2 ways: 1. declaring the above static resources in the service's application.yml or 2. by creating a fat jar and using a transformer to merge the application.yml files

For me, the ideal solution would be to find some way of declaring the static resources in each library and automatically have the static resources when the library is on the classpath.


Solution

  • After a log of digging and tracing through micronaut code, this is what I came up with:

    Define an annotation, e.g.:

    package test;
    
    @Singleton
    @ConfigurationReader(prefix = "static")
    public @interface StaticResource {}
    

    register your static resource in a factory in lib1:

    package lib1;
    
    import test.StatiCResource;
    import io.micronaut.context.annotation.Bean;
    import io.micronaut.context.annotation.Factory;
    import io.micronaut.core.io.ResourceResolver;
    import io.micronaut.web.router.resource.StaticResourceConfiguration;
    import javax.inject.Singleton;
    
    @Factory
    public class Lib1Config {
    
        @Bean
        @StaticResource
        public StaticResourceConfiguration lib1StaticResources(final ResourceResolver resourceResolver) {
            final StaticResourceConfiguration conf = new StaticResourceConfiguration(resourceResolver);
            conf.setPaths(Collections.singletonList("classpath:static/lib1"));
            conf.setMapping("/lib1/**");
            return conf;
        }
    
    }
    

    lib2 can register own resources in a similar way.