【问题标题】:Unable to autowire beans defined using @Bean from two different classes无法自动装配使用来自两个不同类的 @Bean 定义的 bean
【发布时间】:2017-04-26 20:59:10
【问题描述】:

我有两个类 CustomerDAOImpl 和 UserDAOImpl,都使用 @Repository 注释进行了注释。我在每个类中定义并自动装配了@Bean。

@Repository
public class CustomerDAOImpl implements CustomerDAO {
private static final String CUSTOMER_LOCK_INSERT = "INSERT INTO CUSTOMER_LOCKS (customerid, userid, session) VALUES (?, ?, ?)";

    @Bean
    @Lazy(true)
    public PreparedStatement customerLockAddStmt () {
        return cassandraTemplate.getSession().prepare(CUSTOMER_LOCK_INSERT);
    }

    @Autowired
    @Lazy
    PreparedStatement customerLockAddStmt;

    @Autowired
    CassandraOperations cassandraTemplate;

    public void create(CustomerLock lock) {
    ...
    Statement statement = customerLockAddStmt.bind(lock.customerId,lock.userId, lock.sessionId);
    cassandraTemplate.execute(statement);

    }

   }

完全相同的方式,我在 UserDAOImpl 类方法中定义、自动装配和使用了以下 bean(仅显示 bean 定义和自动装配代码以保持它的简洁和简短):

    @Bean
    @Lazy(true)
    public PreparedStatement userAddStmt () {
        return cassandraTemplate.getSession().prepare(USER_INSERT);
    }

    @Bean
    @Lazy(true)
    public PreparedStatement userUpdateStmt () {
        return cassandraTemplate.getSession().prepare(USER_UPDATE);
    }

    @Autowired
    @Lazy
    PreparedStatement userAddStmt;

    @Autowired
    @Lazy
    PreparedStatement userUpdateStmt;

    @Autowired
    CassandraOperations cassandraTemplate;

   public void update(User user){
   //Beans userAddStmt and userUpdateStmt defined and autowired in this class are being used here
   ....
   }

现在这两个 DAO Bean 都在我的服务类 OrderServiceImpl 中自动装配(使用 @Service 注释);这是sn-p:

@Service
    public class OrderServiceImpl implements OrderService {
       @Autowired
       UserDAO userDAO;
       @Autowired
       CustomerDAO customerDAO;

       public void createOrder(Order order) {
       ....
       customerDAO.create(CustomerLock); // Getting the exception on this line
       ....
       userDAO.update(user);
       ....
       }
    }

当 OrderService 代码执行“customerDAO.create(CustomerLock);”时,我遇到了这个异常。

没有定义 [com.datastax.driver.core.PreparedStatement] 类型的合格 bean:预期的单个匹配 bean 但找到了 2:userAddStmt,userUpdateStmt"。

收到此错误后,我在 "customerLockAddStmt" bean 定义中添加了属性 name="customerLockAddStmt" 并在自动装配此 bean 时使用了 @Qualifier("customerLockAddStmt") ,它工作但现在由于相同的原因在下一行失败连接到 userDAOImpl 的 bean 出错:

userDAO.update(user); 

没有定义类型 [com.datastax.driver.core.PreparedStatement] 的合格 bean:预期的单个匹配 bean,但找到 1:customerLockAddStmt"。

有人可以帮忙吗?

【问题讨论】:

  • ...对另一个应用相同
  • 感谢@ɐuıɥɔɐɯ的快速回复。您的意思是使用限定符进行自动装配?这是这种情况下的唯一选择吗?如果我在所有 DAO 实现都扩展的 Base DAO 类中定义所有 PreparedStatement bean,它是否适用于第一个场景(不使用限定符)?
  • 另外,我在哪里可以很好地解释为什么它没有找到其他preparedstatment bean,我认为所有bean 都会出现在spring 上下文中。

标签: java spring autowired


【解决方案1】:

Spring IoC 容器将使用配置管理对象之间的依赖关系;它根据您的配置连接相关对象、实例化和提供它们。如果你有多个相同类型的 bean 没关系,容器会处理它直到你需要它们——这就是你的情况。

你有多个相同类型的bean,它们确实可以被注入,但是容器无法弄清楚你当时要求的是什么,所以基本上您需要对选择过程进行更多控制,因此可以使用 Spring 的 @Qualifier 注释。

另一方面,如果你有很多注解驱动的注入,不要主要使用@Autowired;而是使用语义上定义的@Resource,通过其唯一名称识别特定目标组件,声明的类型与匹配过程无关。

更新:您可以参考this 的帖子,也可以参考Spring Framework Reference Documentation (Dependency Injection and Inversion of Control)

【讨论】:

    猜你喜欢
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-22
    • 2016-09-27
    • 2017-12-18
    • 2016-09-30
    相关资源
    最近更新 更多