javaspringspring-bootspring-autoconfiguration

How to create an "Enable" annotation in Spring Boot that can pass values to a configuration?


I'm using Spring Boot 3.2 and I'm trying to write an annotation that imports some spring configuration. This is what I have:

@Configuration
public class CustomAutoConfiguration {

    @Bean
    public CustomBean customBean() {      
        return new CustomBean();
    }
}

and then I have this annotation:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(CustomAutoConfiguration.class)
public @interface EnableCustomAutoConfiguration {
}

which I can then enable like this:

@SpringBootApplication
@EnableCustomAutoConfiguration
public class MySpringBootApplication {

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

But I need the CustomBean to include some value specified in the @EnableCustomAutoConfiguration annotation. For example, if I modify the EnableCustomAutoConfiguration like this:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(CustomAutoConfiguration.class)
public @interface EnableCustomAutoConfiguration {
   String someString();
}

I then want the someString to be accessible in CustomAutoConfiguration:

@Configuration
public class CustomAutoConfiguration {

    @Bean
    public CustomBean customBean() {      
        String someString = ?? // How can I get the value of "someString" defined in the annotation?
        return new CustomBean(someString);
    }
}

How can I achieve this?


Solution

  • You could find the annotated bean via the ApplicationContext

    something like:

     @Bean
     public CustomBean customBean(ApplicationContext applicationContext) {      
        // get the annotated bean name
        Optional<String> customAutoConfigurationBeanName = 
          applicationContext.getBeansWithAnnotation(EnableCustomAutoConfiguration.class)
                            .keySet().stream().findFirst();
       if (customAutoConfigurationBeanName.isEmpty()) return null;
       // get the EnableCustomAutoConfiguration annotation
       EnableCustomAutoConfiguration enableCustomAutoConfiguration = 
         applicationContext.findAnnotationOnBean(customAutoConfigurationBeanName.get(),
                            EnableCustomAutoConfiguration.class);
      return new CustomBean(enableCustomAutoConfiguration.someString());
    }