当我们可以为 bean 命名时,为什么还要使用限定符呢?

发布于 2025-01-20 16:45:55 字数 989 浏览 0 评论 0原文

当同一类型(类)的不同 bean 可以有不同的名称时,为什么还要对 @Bean 使用限定符?

@Bean
@Qualifier("fooConfig")
public Baz method1() {

}

下面的代码是不是更简洁?

@Bean("fooConfig")
public Baz method1() {

}

如果我创建两个具有不同名称的相同类型的bean(使用@Bean注释),那么我们可以使用@Qualifier注释(可以添加在字段/构造函数参数/setter上)在另一个bean中专门注入它们吗?


@Bean("fooConfig")
public Baz method1(){

}

@Bean("barConfig")
public Baz method2(){

}

// constructor parameter of a different bean
final @Qualifier("fooConfig") Baz myConfig

如果上述情况成立,那么我们在哪里使用@Qualifier(与@Bean或@Component一起使用)而不是给bean命名,如下所示?


@Bean
@Qualifier("fooConfig")
public Baz method1(){

}

@Bean
@Qualifier("barConfig")
public Baz method2(){

}

// constructor parameter of a different bean
final @Qualifier("fooConfig") Baz myConfig

Why do we use qualifiers with @Bean when we can have different names for different beans of the same type (class)?

@Bean
@Qualifier("fooConfig")
public Baz method1() {

}

Isn't the following code more clean?

@Bean("fooConfig")
public Baz method1() {

}

If I create two beans of the same type with different names (using @Bean annotation), then can we inject them specifically using the @Qualifier annotation(can be added on field/constructor parameter/setter) in another bean?


@Bean("fooConfig")
public Baz method1(){

}

@Bean("barConfig")
public Baz method2(){

}

// constructor parameter of a different bean
final @Qualifier("fooConfig") Baz myConfig

If the above is true, then where do we use @Qualifier (with @Bean or @Component) instead of giving the bean a name as shown below?


@Bean
@Qualifier("fooConfig")
public Baz method1(){

}

@Bean
@Qualifier("barConfig")
public Baz method2(){

}

// constructor parameter of a different bean
final @Qualifier("fooConfig") Baz myConfig

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

虚拟世界 2025-01-27 16:45:55

我非常喜欢另一种工作方式。当然,如果您为豆提供一个唯一的名称,那就是您所需要的?

给定下面的示例,很容易看出,春季将根据用于创建bean的方法名称命名bean。换句话说,如果您给豆类明智的名称,则代码应该变得不言自明。将豆类注入其他类时,这也有效。

最终结果是:

  • Spring将根据用于创建它们的方法来命名您的豆类。
  • 如果您导入Bean,Spring将尝试在Bean名称上匹配。
  • 如果您尝试导入与名称不匹配的bean,则Spring将尝试匹配该类。
  • 如果您的注入字段名称与Bean名称不匹配,并且您的BEAN实例不止一个实例,则Spring会在启动上引发一个例外,因为它不知道要注入哪个。

让我们不要过度完整的春天。

@Bean
mqConnectionFactory() {
    ConnectionFactory connectionFactory = new MQXAConnectionFactory();
    return connectionFactory;
}

@Bean 
public ConnectionFactory pooledConnectionFactory(ConnectionFactory mqconnectionFactory) {
    JmsPoolConnectionFactory connectionFactory = new JmsPoolConnectionFactory();
    connectionFactory.setConnectionFactory(mqConnectionFactory);
    return connectionFactory;
}

@Bean 
public ConnectionFactory cachingConnectionFactory(ConnectionFactory mqConnectionFactory) {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
    connectionFactory.setTargetConnectionFactory(mqConnectionFactory);
    return connectionFactory;
} 

@Bean
public JmsTemplate jmsTemplate(ConnectionFactory cachingConnectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate();
    jmsTemplate.setConnectionFactory(cachingConnectionFactory);
    return jmsTemplate;
}

@Bean
public DefaultMessageListenerContainer messageListenerContainer(ConnectionFactory pooledConnectionFactory) {
    DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
    container.setConnectionFactory(pooledConnectionFactory);
    ...
    return container;
}

I quite like a different way of working. Surely if you provide a unique name for your bean, then that is all you need?

Given the example below, its easy to see that Spring will name the beans based on the method name used to create the beans. In other words, if you give your beans sensible names, then the code should become self-explanatory. This also works when injecting beans into other classes.

The end result of this is:

  • Spring will name your beans based on the method used to create them.
  • If you import a bean, Spring will try to match on the bean name.
  • If you try to import a bean that does not match the name, Spring will attempt to match the class.
  • If your injected field name does not match the bean name and there are more than one instance of your bean, Spring will throw an exception on startup as it won't know which one to inject.

Lets not over-complicate Spring.

@Bean
mqConnectionFactory() {
    ConnectionFactory connectionFactory = new MQXAConnectionFactory();
    return connectionFactory;
}

@Bean 
public ConnectionFactory pooledConnectionFactory(ConnectionFactory mqconnectionFactory) {
    JmsPoolConnectionFactory connectionFactory = new JmsPoolConnectionFactory();
    connectionFactory.setConnectionFactory(mqConnectionFactory);
    return connectionFactory;
}

@Bean 
public ConnectionFactory cachingConnectionFactory(ConnectionFactory mqConnectionFactory) {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
    connectionFactory.setTargetConnectionFactory(mqConnectionFactory);
    return connectionFactory;
} 

@Bean
public JmsTemplate jmsTemplate(ConnectionFactory cachingConnectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate();
    jmsTemplate.setConnectionFactory(cachingConnectionFactory);
    return jmsTemplate;
}

@Bean
public DefaultMessageListenerContainer messageListenerContainer(ConnectionFactory pooledConnectionFactory) {
    DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
    container.setConnectionFactory(pooledConnectionFactory);
    ...
    return container;
}
も星光 2025-01-27 16:45:55
  1. 豆子有名字。他们没有资格赛。 @Qualifier是一个注解,用来告诉Spring要注入的Bean的名称。

  1. 不。

  1. 默认限定符是接口的唯一实现(示例如下,第四个问题)或具有特定返回类型的唯一方法。在这种情况下,您不需要指定@Qualifier。 Spring 足够聪明,能够找到自己。

例如:

@Configuration
public class MyConfiguration {
    @Bean
    public MyCustomComponent myComponent() {
        return new MyCustomComponent();
    }
}

如果您尝试在某处注入 myComponent,Spring 足够聪明,可以找到上面的 bean。因为只有一个返回类型为MyCustomComponent的Bean。但如果有几个方法会返回 MyCustomComponent,那么您必须告诉 Spring 使用 @Qualifier 注解注入哪一个。

旁注:默认情况下,@Bean 注解 Spring 使用方法名称作为 bean 名称。您还可以指定其他名称,例如 @Bean("otherComponent")。


  1. 您有一个接口和几个实现它的类。您注入接口的 bean。 Spring如何知道应该使用哪个类?

这是您的界面:

public interface TestRepository{}

这是您的实现 1:

@Repository
public class Test1Repository implements TestRepository{}

您的实现 2:

@Repository
public class Test2Repository implements TestRepository{}

现在您正在注入它:

private final TestRepository testRepository;

public TestServiceImpl(TestRepository testRepository) {
    this.testRepository= testRepository;
}

问题! Spring 应该如何知道要注入哪个类?测试1还是测试2?这就是为什么你用 @Qualifier 告诉它哪个类。

private final TestRepository testRepository;

public TestServiceImpl(@Qualifier("test1Repository") TestRepository testRepository) {
    this.testRepository= testRepository;
}
  1. Beans have names. They don't have qualifiers. @Qualifier is annotation, with which you tell Spring the name of Bean to be injected.

  1. No.

  1. Default Qualifier is the only implementation of the interface(example is below, 4th question) or the only method with a particular return type. You don't need to specify the @Qualifier in that case. Spring is smart enough to find itself.

For example:

@Configuration
public class MyConfiguration {
    @Bean
    public MyCustomComponent myComponent() {
        return new MyCustomComponent();
    }
}

If you will try to inject myComponent somewhere, Spring is smart enough to find the bean above. Becaude there is only one Bean with return type MyCustomComponent. But if there was a couple of methods, that would return MyCustomComponent, then you would have to tell Spring which one to inject with @Qualifier annotation.

SIDENOTE: @Bean annotation by default Spring uses the method name as a bean name. You can also assign other name like @Bean("otherComponent").


  1. You have one Interface, and a couple of Classes implementing it. You inject bean of your interface. How can Spring know which Class should be used?

This is you interface:

public interface TestRepository{}

This is your implementation 1:

@Repository
public class Test1Repository implements TestRepository{}

Your implementation 2:

@Repository
public class Test2Repository implements TestRepository{}

Now you are injecting it like:

private final TestRepository testRepository;

public TestServiceImpl(TestRepository testRepository) {
    this.testRepository= testRepository;
}

QUESTION! How is Spring supposed to know which class to inject? Test1 or Test2? That's why you tell it with @Qualifier which class.

private final TestRepository testRepository;

public TestServiceImpl(@Qualifier("test1Repository") TestRepository testRepository) {
    this.testRepository= testRepository;
}
野の 2025-01-27 16:45:55

我更喜欢不同的方法使用@Qualifier

  1. 创建通用接口
公共接口CommonFooBar{
公共字符串 commonFoo();
公共字符串commonBar();
}
  1. 延伸至每项服务
公共接口 FooService 扩展 CommonFooBar {

}

公共接口 BarService 扩展 CommonFooBar {

}
  1. 然后将其用于您的课堂

<前><代码>@Autowired
FooService fooService;

或者

@Autowired
酒吧服务酒吧服务;

因此,我们可以为每个接口定义单一职责,这种隔离对于每个初级人员来说都更具可读性。

I Prefer different method to not using @Qualifier

  1. Create common Interface
public interface CommonFooBar{
public String commonFoo();
public String commonBar();
}
  1. Extends to each service
public interface FooService extends CommonFooBar {

}

public interface BarService extends CommonFooBar {

}
  1. Then using it to your class
@Autowired
FooService fooService;

or

@Autowired
BarService barService;

so, we can defined the single responsibility to each interface and This kind of segregation is more readable to every junior.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文