2017-02-14 6 views
0

Я складываю с вышеупомянутым исключением и действительно не понимаю, почему он появился. Я использую весенний ботинок и объявляю bean bean через аннотацию.NoSuchBeanDefinitionException: Отсутствие квалификационного компонента типа

Применение выполняется этим классом:

@SpringBootApplication 
public class Application extends SpringBootServletInitializer { 


@Override 
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 

    return application.sources(Application.class); 
} 

public static void main(String[] args) throws Exception { 
    SpringApplication.run(Application.class, args); 

} 

Моя проблема боб имеет следующее заявление:

@Service 
public class OrderSvc extends AbstractService implements DAOService { 

я пытаюсь поставить его в следующем боба:

@RestController 
public class OrderController { 

@Autowired 
CarSvc carSvc; 

@Autowired 
OrderSvc orderSvc; 

и появляется исключение: Could not autowire field: biz.Services.OrderSvc biz.controllers.rest.administrator.OrderController.orderSvc; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [biz.Services.OrderSvc] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Я также CarSvc боб, который находится в том же пакете, OrderSvc и проходит одни и те же классы, но нет никаких проблем с этим инъекционного

@Service 
public class CarSvc extends AbstractService implements DAOService<Car> { 

Есть ли у вас какие-либо идеи, почему появляется это исключение?

+0

Вы не объявили тип при реализации универсального интерфейса 'DaoService ' в 'OrderSvc'. Опечатка? –

+0

Да, это моя вина, но это не решает мою проблему.У меня все еще есть проблема с инъекцией –

+0

Является ли 'OrderSvc' реализует' DAOService 'или' DAOService '? –

ответ

1

Попробуйте в autowire ваши бобы используя интерфейсы, а не реализации:

@RestController 
public class OrderController { 

    @Autowired 
    @Qualifier("carSvc") 
    DAOService carSvc; 

    @Autowired 
    @Qualifier("orderSvc") 
    DAOService orderSvc; 

} 

Edit: Но до этого вы должны дать имена вашим услугам:

@Service("carSvc") 
public class CarSvc extends AbstractService implements DAOService<Car> {} 

@Service("orderSvc") 
public class OrderSvc extends AbstractService implements DAOService<Order> {} 

Что происходит здесь является то, что Spring генерирует прокси-серверы ваших сервисов на основе CarSvc, OrderSvc и реализует DAOService, но не расширяет CarSvc, OrderSvc.

//somthing like this 
class CarSvcProxy implement DAOService { 

    public Object getOrder(Long id) { 

     try { 

      // ... 

      txManager.commit(); 

     } catch (Exception ex) { 
      txManager.rollback(); 
     } 
    } 
} 

@RestController 
public class OrderController { 

    //So when you do this : 
    @Autowired 
    CarSvc carSvc; 

    //it's somehow like if you did : 
    CarSvc carSvc = new CarSvcProxy(); //carSvc != CarSvcProxy 

    //But this will work : 
    DAOService carSvc = new CarSvcProxy(); //because CarSvcProxy implement DAOService 

} 
0

Я нашел код, который приводит к исключению, но я действительно не понимаю, почему.

В моей OrderSvc есть следующий метод:

@Transactional(readOnly = true) 
public Object getOrder(Long id) { 
    final Order order = getDAO().findOne(id); 
    OrderDTO orderDTO = modelMapper.map(order, OrderDTO.class); 
    return orderDTO; 
} 

Так что, если аннотация @Transactional(readOnly = true) был исключено приложение может быть тем или иная строчка без проблем ... Есть ли у вас какие-либо идеи, почему это аннотация привести к NoSuchBeanDefinitionException?

2

Spring создает прокси для классов, которые декларируют @Transactional, так что он может добавить транзакционного поведения и переадресованные вызовы на ваш объект. Если компонент расширяет любой интерфейс, Spring собирается создать динамический прокси с использованием API JDK Reflection, и это может быть сделано только через интерфейс. Прокси-сервер - это новый объект, реализующий один и тот же интерфейс. Таким образом, ваш целевой компонент не является вашей реализацией, а прокси-сервером. Вот почему вы получаете исключение из категории исключающих компонентов.

CGLIB, с другой стороны, может создавать прокси-сервер путем подкласса.

Итак, чтобы заставить его работать, вам нужно изменить свой тип bean-интерфейса на интерфейс, или вы можете настроить cglib, используя @EnableTransactionManagement (proxyTargetClass = true).

+0

Благодарим вас за объяснение. –