2016-12-12 2 views
0

У меня есть два класса CustomerDAOImpl и UserDAOImpl, оба аннотированные с аннотацией @Repository. У меня есть @Bean, определяемый и автообновленный в каждом классе.Невозможно использовать autowire beans, определенные с помощью @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); 

    } 

    } 

Точно таким же образом, я определил, autowired и используются следующие фасолью в методах класса UserDAOImpl (только с указанием определения фасоли и автоматического связывания кода, чтобы держать его в чистоте и короткий здесь):

@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 Beans проходят аутсорсинг в моем классе обслуживания OrderServiceImpl (аннотируются с помощью @Service); вот фрагмент:

@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] определяется: ожидается совпадение одного боба, но нашел. 2: userAddStmt, userUpdateStmt»

После того, как эту ошибку, я добавил имя атрибута = «customerLockAddStmt» в «customerLockAddStmt» определение компонента и используется @Qualifier («customerLockAddStmt») в то время как этот компонент автоматического связывания, он работал, но теперь он не будет работать на следующей линии из-за той же ошибки для бобов соединённых в userDAOImpl:

userDAO.update(user); 

Определенный компонент типа [com.datastax.driver.core.PreparedStatement] не определен: ожидается si ngle matching bean, но найдено 1: customerLockAddStmt ".

Не могли бы вы помочь?

+0

... применять то же самое к другому –

+0

Спасибо за быстрый ответ @ ɐuıɥɔɐɯ. Вы имеете в виду использование квалификаторов для автоподготовки? Это единственный вариант в этом сценарии? Будет ли он работать с первым сценарием (не используя квалификаторы), если я определяю все компоненты PreparedStatement в базовом классе DAO, которые расширяют все реализации DAO? – ktewari

+0

Кроме того, где я могу получить хорошее объяснение, почему он не находит другие готовые фасоли, я думал, что все бобы будут присутствовать в весеннем контексте. – ktewari

ответ

1

Контейнер Spring IoC будет управлять зависимостью между объектами с использованием конфигураций; он связывает связанные объекты, создает и передает их на основе вашей конфигурации. Не имеет значения, есть ли у вас несколько бобов того же типа, контейнер будет обрабатывать это до тех пор, пока они вам понадобятся - это ваш случай.

У вас есть несколько компонентов одного и того же типа, и они доступны для инъекций, действительно, но контейнер не могу понять, что это один вы просите в то время, поэтому в основном вам нужно больше контроль над процессом выбора и, следовательно, можно использовать аннотацию Spring @Qualifier.

С другой стороны, если у вас есть много энтродических инъекций по имени, не используйте в основном @Autowired; вместо этого используйте @Resource, который семантически определен для идентификации конкретного целевого компонента по его уникальному имени, причем указанный тип не имеет отношения к процессу сопоставления.

ОБНОВЛЕНИЕ: Вы можете обратиться к сообщению this, а также к Spring Framework Reference Documentation (Dependency Injection and Inversion of Control).

Смежные вопросы