0

I have a config and it's @Import-ed by an annotation. I want the values on the annotation to be accessible by the config. Is this possible?

Config:

@Configuration
public class MyConfig
{
    @Bean
    public CacheManager cacheManager(net.sf.ehcache.CacheManager cacheManager)
    {
        //Get the values in here

        return new EhCacheCacheManager(cacheManager);
    }

    @Bean
    public EhCacheManagerFactoryBean ehcache() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setShared(true);

        return ehCacheManagerFactoryBean;
    }
}

The annotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyConfig.class)
public @interface EnableMyCaches
{
    String value() default "";
    String cacheName() default "my-cache";
}

How would I get the value passed below in my config?

@SpringBootApplication
@EnableMyCaches(cacheName = "the-cache")
public class MyServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyServiceApplication.class, args);
    }
}
Don Rhummy
  • 24,730
  • 42
  • 175
  • 330

2 Answers2

1

Use simple Java reflection:

Class c = MyServiceApplication.getClass();
EnableMyCaches enableMyCaches = c.getAnnotation(EnableMyCaches.class);
String value = enableMyCaches.value();
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • 1
    This requires my code to know beforehand the name of the class with my annotation. But if my class is include as a dependency jar I can't know that – Don Rhummy Oct 04 '17 at 20:51
1

Consider how things like @EnableConfigurationProperties are implemented.

The annotation has @Import(EnableConfigurationPropertiesImportSelector.class) which then imports ImportBeanDefinitionRegistrars. These registrars are passed annotation metadata:

public interface ImportBeanDefinitionRegistrar {

    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

}

You can then get annotation attributes from annotation metadata:

MultiValueMap<String, Object> attributes = metadata
                .getAllAnnotationAttributes(
                        EnableMyCaches.class.getName(), false);
attributes.get("cacheName");
lexicore
  • 42,748
  • 17
  • 132
  • 221