【问题标题】:Can I use another Annotation as the value of the Spring @Qualifier?我可以使用另一个注解作为 Spring @Qualifier 的值吗?
【发布时间】:2021-04-14 02:36:19
【问题描述】:

奇怪的情况,但我正在从 dagger/dropwizard 框架迁移到 Spring。 在旧框架中,代码使用了一堆自定义的@interface Annotations 来指定哪个bean 去哪里。

比如可能有一个注解像

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ForAdmin {}

而且提供者有这样的代码

@Provides
@ForAdmin
static Foobar provideFoobar() { ... }

然后像这样注入

public MyObject(@ForAdmin Foobar foobar) { ... }

在 Spring 世界中,我知道我可以将提供程序翻译成

@Bean("ForAdmin")
public Foobar provideFoobar() { }

然后像这样注入

public MyObject(@Qualifier("ForAdmin") Foobar foobar) { ... }

我想知道是否有办法将现有的@ForAdmin 注释本身作为限定符提供。

类似...

@Bean(ForAdmin.class)
public Foobar provideFoobar() { }

这可能吗?有没有更好的办法?

我想这样做的原因是为了保留原始注解,以便将它们放在那里的开发人员仍然熟悉它们,并且可以通过他们已经知道使用 IDE 的注解来跟踪 bean 和注入。

【问题讨论】:

  • @Nikolai 下面的回答是正确的。另外,我发现了这个definitive source

标签: java spring dependency-injection


【解决方案1】:

您可以使用与以前完全相同的方法

假设一个接口有 2 个实现:

interface Foobar {}

class FoobarAll implements Foobar {}

class FoobarAdmin implements Foobar {}

以及产生@Beans的配置

@Configuration
class FoobarConfig {
    @Bean
    Foobar provideFoobarAll() { return new FoobarAll(); }

    @ForAdmin
    @Bean
    Foobar provideFoobarAdmin() { return new FoobarAdmin(); }
}

一个类 Foobar 被注入

@Component
class FoobarConsumer {
    private final Foobar foobar;

    public FoobarConsumer(@ForAdmin Foobar foobar) {
        this.foobar = foobar;
        System.out.println("I am " + this.foobar.getClass().getSimpleName()); 
        // >>> I am FoobarAdmin
    }
}

附:为了简化您的代码,您甚至不需要@Configuration 来生成@Beans,您可以简单地将@Component@Service Spring 注释放在您的类上。然后 Spring 会自动实例化这些 bean。

@Component
class FoobarAll implements Foobar {}

@ForAdmin
@Component
class FoobarAdmin implements Foobar {}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2020-12-20
    • 1970-01-01
    相关资源
    最近更新 更多