spring 如何在Sping Boot 中创建一个可以将值传递给配置的“Enable”注解?

rqmkfv5c  于 5个月前  发布在  Spring
关注(0)|答案(2)|浏览(46)

我正在使用Sping Boot 3.2,我正在尝试编写一个annotation来导入一些spring配置。这是我所拥有的:

@Configuration
public class CustomAutoConfiguration {

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

字符串
然后我有这样的注解:

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


然后我可以像这样启用:

@SpringBootApplication
@EnableCustomAutoConfiguration
public class MySpringBootApplication {

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


但是我需要CustomBean包含一些在@EnableCustomAutoConfiguration注解中指定的值。例如,如果我像这样修改EnableCustomAutoConfiguration

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


然后,我希望someString可以在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);
    }
}


我如何才能做到这一点?

zmeyuzjn

zmeyuzjn1#

您可以通过ApplicationContext找到带注解的bean
例如:

@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());
}

字符串

vc6uscn9

vc6uscn92#

如果你使用@Import,就没有必要再使用@Configuration了,它们都是将类注入到ioc容器中,如果我理解正确的话,你可以这样使用它们

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

@Slf4j
public class CustomAutoConfiguration implements DeferredImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        AnnotationAttributes attributes = AnnotationAttributes
                .fromMap(metadata.getAnnotationAttributes(EnableCustomAutoConfiguration.class.getName(), true));
        if (attributes == null) {
            log.info("@EnableCustomAutoConfiguration is not present on importing class");
            return new String[0];
        }
        // this  "someString"  is the value of the property under the annotation you defined
        String someString = attributes.getString("someString");

//Depending on the value of the property, 
//determine which configuration class you need to enable to load into the ioc container
        return new String[]{YourConfig.class.getName()};
    }
}

字符串

相关问题