Spring Boot启动报错:无法找到service.ProductService类型的Bean
问题:Spring Boot启动失败,无法找到ProductService Bean
我正在开发一个支持GET、PUT、POST、DELETE请求的Spring Boot应用,启动时遇到报错,多次修改仍无法解决,期望能在浏览器访问http://localhost:8080/products看到页面。
报错信息
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. 2024-01-13T01:58:33.595-05:00 ERROR 10400 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Parameter 0 of constructor in com.example.sqch8ex5.ProductController required a bean of type 'service.ProductService' that could not be found. Action: Consider defining a bean of type 'service.ProductService' in your configuration.
项目结构说明
项目包含以下包结构:
com.example.sqch8ex5:存放启动类和控制器service:存放服务类model:存放实体类
相关代码文件
SqCh8Ex5Application.java
package com.example.sqch8ex5; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SqCh8Ex5Application { public static void main(String[] args) { SpringApplication.run(SqCh8Ex5Application.class, args); } }
ProductController.java
package com.example.sqch8ex5; import model.Product; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import service.ProductService; @Controller public class ProductController { private final ProductService productService; @Autowired public ProductController(ProductService productService){ this.productService = productService; } @GetMapping("/products") public String viewProducts(Model model){ var products = productService.findAll(); model.addAttribute("products", products); return "products.html"; } @PostMapping("/products") public String addProduct(@RequestParam String name, @RequestParam double price, Model model){ Product p = new Product(); p.setName(name); p.setPrice(price); productService.addProduct(p); var products = productService.findAll(); model.addAttribute("products",products); return "products.html"; } }
products.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Home Page</title> </head> <body> <h1>Products</h1> <h2>View products</h2> <table> <tr> <th>PRODUCT NAME</th> <th>PRODUCT PRICE</th> </tr> <tr th:each="p:${products}"> <td th:text="${p.name}"></td> <td th:text="${p.price}"></td> </tr> </table> <h2>Add a product</h2> <form action="/products" method="post"> Name:<input type="text" name="name"><br /> Price:<input type="number" step="any" name ="price"><br /> <buttom type="submit">Add product</buttom> </form> </body> </html>
ProductService.java
package service; import model.Product; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class ProductService { private List<Product> products = new ArrayList<>(); public ProductService() { } public void addProduct(Product p){ products.add(p); } public List<Product> findAll(){ return products; } }
解决方案
核心原因
Spring Boot的@SpringBootApplication注解默认只扫描启动类所在包(com.example.sqch8ex5)及其子包下的组件。而你的ProductService在独立的service包中,不在默认扫描范围内,因此Spring无法识别这个@Service注解的类,无法创建对应的Bean注入到控制器中。
解决方法(二选一即可)
方法1:调整包结构(推荐)
把ProductService移动到启动类所在包的子包中:
- 修改
ProductService的包声明为:package com.example.sqch8ex5.service; - 同时修改
ProductController中的导入语句:import com.example.sqch8ex5.service.ProductService;
这样Spring会自动扫描到这个服务类,创建Bean。
方法2:扩展组件扫描范围
在启动类的@SpringBootApplication注解中指定要扫描的所有包:
@SpringBootApplication(scanBasePackages = {"com.example.sqch8ex5", "service", "model"})
这样Spring会扫描指定的三个包下的所有带有@Service、@Controller等注解的类。
额外修复点
products.html中的提交按钮标签拼写错误:<buttom>应该改为<button>,否则按钮可能无法正常触发提交操作:
<button type="submit">Add product</button>
内容的提问来源于stack exchange,提问作者Dheeraj A Kumar
相关产品推荐
相关产品推荐

