首页 > 解决方案 > Spring:如何使用注释从同一个类中创建两个不同的 bean?

问题描述

假设我们有以下类:

public class Service {
    private String name;

    public Service(String name) {
        this.name = name;
    }

    /// other methods
}

假设我想从同一个类中生成两个不同的 bean。如果我使用 xml,这很容易:

<beans>
   <bean id="service1" class="Service">
      <constructor-arg value="first service" />
   </bean>
   <bean id="service2" class="Service">
      <constructor-arg value="second service" />
   </bean>
</beans>

我的问题是如何使用弹簧注释生成它。

编辑:此链接中的答案不适合我的问题。在这个链接中,类 MySecondComponent 生成了两次,但它有一个默认构造函数,我们不会为每个实例传递不同的参数/依赖项。

标签: javaspring

解决方案


这是在 Java 中做同样事情的一种方法(从 spring 3.x 开始):

@Configuration
public class MySampleConfiguration {

   @Bean
   public Service service1() {
      return new Service("first service");
   }

   @Bean
   public Service service2() {
      return new Service("second service");
   }
}

更新 1

根据OP的评论:

有不同的用例,有些需要指定 bean 名称,有些则不需要。

用例 1:

比如说,有一个需要实例化的 bean,比如说service1

public class SampleBean {
    private final Service service;

    public SampleBean(Service service) {
       this.service = service;
    }
}

理想情况下,您不想在SampleBean类的代码中指定限定符,因为它在某种程度上扼杀了依赖注入原则。但是,您可以在配置中执行此操作:

@Configuration
public class MySampleConfigurationWithQualifier {

    @Bean(name = "service1")
    public Service service1() {
       return new Service1("first service");
    }

    @Bean(name = "service2")
    public Service service2() {
       return new Service2("second service");
    }

    @Bean
    public SampleBean sampleBean(@Qualifier("service1") Service service) {
       return new SampleBean(service);
    }
}

用例 2:

比如说,这些服务应该以某种集合(比如列表)的形式注入到另一个 bean 中。

在这种情况下,无需指定name属性

public class SampleBean2 {

   private final List<Service> services;

   public SampleBean2(List<Service> services) {
      this.services = services;
   }

   public void notifyOnSomeEvent(Event evt) {
      for(Service service : services) {
        service.notify(evt);
      }
   }
}

在这种情况下,配置可能如下所示:

@Configuration
public class MySampleConfigurationWithListInjection {

    @Bean(name = "service1")
    public Service service1() {
       return new Service1("first service");
    }

    @Bean(name = "service2")
    public Service service2() {
       return new Service2("second service");
    }

    @Bean
    public SampleBean2 sampleBean2(List<Service> services) {
       return new SampleBean2(services);
    }
}


推荐阅读