简体   繁体   English

我可以使用另一个 Annotation 作为 Spring @Qualifier 的值吗?

[英]Can I use another Annotation as the value of the Spring @Qualifier?

Weird situation, but I'm doing a migration from dagger/dropwizard framework into Spring. In the old framework, the code used a bunch of custom @interface Annotations to specify which bean goes where.奇怪的情况,但我正在从 dagger/dropwizard 框架迁移到 Spring。在旧框架中,代码使用一堆自定义 @interface 注释来指定哪个 bean 去哪里。

For example, there may be an annotation like例如,可能有这样的注释

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

And the providers have code like this供应商有这样的代码

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

And injects like so像这样注入

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

In the Spring world, I know I can translate the provider to在 Spring 的世界里,我知道我可以将 provider 翻译成

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

And inject like so像这样注入

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

I'm wondering if there is a way to provide the existing @ForAdmin annotation itself as the Qualifier.我想知道是否有办法提供现有的@ForAdmin注释本身作为限定符。

Something like...就像是...

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

Is this possible?这可能吗? Is there a better way?有没有更好的办法?

The reason I'd like to do this is to preserve the original annotations so the developers who put them there are still familiar with them and can trace the bean and injection through the annotation they already know about using the IDE.我想这样做的原因是为了保留原始注释,以便将它们放在那里的开发人员仍然熟悉它们,并且可以通过他们已经知道的关于使用 IDE 的注释来跟踪 bean 和注入。

You can use exactly same approach as you used before您可以使用与之前完全相同的方法

Assuming an interface with 2 implementations:假设一个接口有 2 个实现:

interface Foobar {}

class FoobarAll implements Foobar {}

class FoobarAdmin implements Foobar {}

and a configuration that produces @Bean s和产生@Bean的配置

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

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

and a class Foobar is injected into并注入一个 class 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
    }
}

PS To simplify your code you don't even need a @Configuration to produce @Bean s, you can simply place either @Component or @Service Spring annotation on your classes. PS 为了简化您的代码,您甚至不需要@Configuration来生成@Bean s,您可以简单地在您的类上放置@Component@Service Spring 注释。 Then Spring will automatically instantiate these beans.然后Spring会自动实例化这些bean。

@Component
class FoobarAll implements Foobar {}

@ForAdmin
@Component
class FoobarAdmin implements Foobar {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM