You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义@EnableX注解如何与导入的配置类共享其属性?

如何让自定义@EnableX注解与导入的配置类共享属性

下面提供两种Spring原生支持的实现方式,完全可以实现你想要的属性传递效果:

方式一:让配置类实现ImportAware接口

通过ImportAware接口,配置类可以直接获取到导入它的@EnableInteger注解的元数据,从而读取到注解属性值。

修改后的代码示例

  1. 保持@EnableInteger注解定义不变:
import org.springframework.context.annotation.Import;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(GenericTest.SomeConfig.class)
public @interface EnableInteger {
    boolean odd() default false;
}
  1. 修改配置类SomeConfig,实现ImportAware接口:
@Configuration
static class SomeConfig implements ImportAware {
    private boolean generateOdd;

    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata) {
        // 解析@EnableInteger注解的属性
        Map<String, Object> annotationAttrs = importMetadata.getAnnotationAttributes(EnableInteger.class.getName());
        if (annotationAttrs != null) {
            this.generateOdd = (boolean) annotationAttrs.get("odd");
        }
    }

    @Bean
    Integer someInteger() {
        // 根据注解属性生成对应整数
        return generateOdd ? 41 : 42;
    }
}
  1. 测试类用法不变:
@ExtendWith(SpringExtension.class)
@EnableInteger(odd = true)
public class GenericTest {
    @Autowired
    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    Integer someInteger;

    @Test
    void test() {
        // 验证注入的是奇数
        assert someInteger % 2 == 1;
    }
}

方式二:使用ImportBeanDefinitionRegistrar注册Bean

如果不想让配置类依赖Spring接口,可以自定义ImportBeanDefinitionRegistrar,直接根据注解属性动态注册Bean。

修改后的代码示例

  1. 修改@EnableInteger注解,改为导入自定义的注册器:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(IntegerBeanRegistrar.class)
public @interface EnableInteger {
    boolean odd() default false;
}
  1. 实现自定义注册器IntegerBeanRegistrar:
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;

public class IntegerBeanRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 获取@EnableInteger的odd属性值
        Map<String, Object> annotationAttrs = importingClassMetadata.getAnnotationAttributes(EnableInteger.class.getName());
        boolean isOdd = annotationAttrs != null ? (boolean) annotationAttrs.get("odd") : false;

        // 创建Bean定义,指定要生成的整数
        GenericBeanDefinition beanDef = new GenericBeanDefinition();
        beanDef.setBeanClass(Integer.class);
        beanDef.setFactoryMethodName("valueOf");
        beanDef.getConstructorArgumentValues().addGenericArgumentValue(isOdd ? 41 : 42);

        // 注册名为someInteger的Bean
        registry.registerBeanDefinition("someInteger", beanDef);
    }
}
  1. 测试类无需修改,注入的someInteger会根据@EnableInteger(odd = true)生成对应奇数。

这两种方式都是Spring官方注解(比如@EnableAsync、@EnableCaching)常用的实现逻辑,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 17:13:21