【问题标题】:NoSuchBeanDefinitionException: No qualifying bean of type [duplicate]NoSuchBeanDefinitionException:没有类型的限定 bean [重复]
【发布时间】:2017-07-02 03:25:06
【问题描述】:

我与上述异常叠加,并没有低估它出现的原因。我正在使用spring boot并通过注解声明bean。

应用程序由此类执行:

@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);

}

我的问题 bean 有以下声明:

@Service
public class OrderSvc extends AbstractService implements DAOService {

我尝试将其放入以下 ​​bean:

@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 bean,它与 OrderSvc 位于同一个包中,并扩展了相同的类,但注入没有问题

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

您知道为什么会出现此异常吗?

【问题讨论】:

  • OrderSvc 中实现泛型接口DaoService&lt;T&gt; 时没有声明类型。错字?
  • 是的,这是我的错,但这并不能解决我的问题。我仍然有注射的问题
  • OrderSvc 是实现DAOService&lt;Car&gt; 还是DAOService&lt;any_other&gt;
  • @RamanujaR OrderSvc 实现 DAOService&lt;Order&gt;

标签: java spring spring-boot dependency-injection


【解决方案1】:

Spring 为声明 @Transactional 的类创建代理,以便它能够添加事务行为并拦截对您的对象的调用。如果 bean 扩展了任何接口,Spring 将使用 JDK Reflection API 创建一个动态代理,这只能通过接口完成。代理是一个实现相同接口的新对象。所以你的目标 bean 不是你的实现,而是一个代理。这就是为什么你得到一个不合格的 bean 异常。

另一方面,CGLIB 可以通过子类化来创建代理。

因此,要使其正常工作,您需要将 bean 类型更改为接口,或者您可以使用 @EnableTransactionManagement(proxyTargetClass = true) 配置 cglib。

【讨论】:

  • 感谢您的解释。
【解决方案2】:

尝试使用接口而不是实现来自动装配 bean:

@RestController
public class OrderController {

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

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

}

编辑:但在此之前,您必须为您的服务命名:

@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

}

【讨论】:

    【解决方案3】:

    我找到了导致异常的代码,但我真的不明白为什么。

    在我的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 吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      • 2020-06-18
      • 2020-06-10
      • 1970-01-01
      • 1970-01-01
      • 2017-04-05
      相关资源
      最近更新 更多