【问题标题】:Spring configuration in Java - Create and use 2 beans of same class NOT using AutowiredJava 中的 Spring 配置 - 创建和使用 2 个不使用 Autowired 的相同类的 bean
【发布时间】:2016-12-05 10:00:36
【问题描述】:

我知道如何创建和使用两个相同类型的 Spring bean 的问题之前已经回答过,并且我已经阅读了一些关于 @Qualifier 和 @Resource 的内容,但我看到的所有答案都是在自动装配的情况下。在我的情况下,我尝试使用 bean 的地方位于配置文件的另一部分,所以我不确定解决方案的哪些部分适用。我还有一个案例是我们正在以多种方式进行配置(xml 配置文件和带有 @Configuration 注释的 java 文件。这是代码的样子

import com.this.that.AuthProvider;
@Configuration
...
    @Bean
    public AuthProvider buildAuthProvider() {
        return new AuthProvider(someotherbean);
    }

    @Bean
    public MyConnectionManager buildMyConnectionManager(AuthProvider authProvider) {
        return new MyConnectionManager(authProvider);
    }
    ...

另一个spring config xml文件导入application-config.xml

  <bean id="MyAuthProvider" class="com.this.that.AuthProvider">
    <constructor-arg type="java.lang.String" ref="somedifferentbean" />
  </bean>

  <bean id="MyClient" class="com.that.this.MyClient">
    <constructor-arg type="com.this.that.AuthProvider"
      ref="MyAuthProvider" />
  </bean>

当我这样做时,尝试在 Java 配置文件中创建 MyConnectionManager 时出错。错误在构造函数 arg 上,带有以下信息) org.springframework.beans.factory.UnsatisfiedDependencyException .. (excpected single bean but found 2: MyAuthProvider, buildMyConnectionManager())

我还在这里看到另一个 bean 引用 AuthProvider 类,但它不只是将其指定为 bean 构造函数的参数,而是使用无参数构造函数并使用“buildAuthProvider()”方法创建一个新的 AuthProvider。我没有看到任何关于该问题或在 xml 文件中创建的 bean 的投诉,但我不确定此错误是否只是掩盖了其他错误。

有人可以帮我弄清楚如何拥有这两个独立的豆子吗?它们是使用传递给构造函数的不同值创建的,因此在这种情况下我不能重用同一个 bean。

【问题讨论】:

    标签: java xml spring configuration javabeans


    【解决方案1】:

    您可以使用限定符来区分这两个 bean。

    @Bean
    @Qualifier("myJDBCTemplate")
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
    
    @Autowired
    @Qualifier("myJDBCTemplate")
    private JdbcTemplate jdbcTemplate;
    

    【讨论】:

      【解决方案2】:

      当使用多个相同类型的 bean 时,您需要使用名称来限定它们。在 XML 配置中,这很自然地出现在 name="" 属性中。在基于 Java 的配置中,您需要将名称添加到注解中,@Bean(name = "")

      接下来,您可以从 Spring 上下文中的任何位置引用 bean。在 Java 中,您将使用 @Qualifier 注释,它在声明 Java bean 或使用 @Autowired 注释注入 Spring 托管类时起作用。

      Java配置示例:

      @Configuration
      public class ApplicationConfiguration {
      
          /**
           * Define bean-one, which can be referenced in Java config or XML config.
           * @return
           */
          @Bean(name = "bean-one")
          public String whoAmI(){
              return "bean 1.";
          }
      
          /**
           * Create a bean with the who am I from the XMl config.
           * @param whoAmI
           * @return
           */
          @Bean(name = "xml-message")
          public String xmlMessage(@Qualifier("bean-two") String whoAmI){
              return "I am " + whoAmI;  // I am bean 2
          }
      
          /**
           * Define the bean with the who am I from the Java config
           * @param whoAmI
           * @return
           */
          @Bean(name="java-message")
          public String javaMessage(@Qualifier("bean-one") String whoAmI){
              return "I am " + whoAmI; // I am bean 1
          }
      }
      

      请注意@Qualifier注解的位置,如果不在方法参数前面,它将不起作用。

      XML 配置示例:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
      
      
          <!-- Find my other context -->
          <context:annotation-config />
          <context:component-scan base-package="test.spring"/>
      
          <!-- Declare bean to to be injected into the any of the message objects. -->
          <bean class="java.lang.String" name="bean-two">
              <constructor-arg value="bean two"/>
          </bean>
      
          <!-- Notice that we reference Java config "Bean-One" by using the name assigned -->
          <bean class="java.lang.String" name="xml-message-two">
              <constructor-arg ref="bean-one"/>
          </bean>
      
          <!-- Notice that we reference Java config "Bean-Two" by using the name assigned -->
          <bean class="java.lang.String" name="java-message-two">
              <constructor-arg ref="bean-two"/>
          </bean>
      
      </beans>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-02
        • 1970-01-01
        • 1970-01-01
        • 2014-07-20
        • 2021-08-02
        • 2019-11-11
        相关资源
        最近更新 更多