我有
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@ComponentScan(basePackages = {"hello","com.ensat.controllers"})
@EntityScan("com.ensat.entities")
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);
}
}
ProductController.java
package com.ensat.controllers;
import com.ensat.entities.Product;
import com.ensat.services.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Product controller.
*/
@Controller
public class ProductController {
private ProductService productService;
@Autowired
public void setProductService(ProductService productService) {
this.productService = productService;
}
/**
* List all products.
*
* @param model
* @return
*/
@RequestMapping(value = "/products", method = RequestMethod.GET)
public String list(Model model) {
model.addAttribute("products", productService.listAllProducts());
System.out.println("Returning rpoducts:");
return "products";
}
/**
* View a specific product by its id.
*
* @param id
* @param model
* @return
*/
@RequestMapping("product/{id}")
public String showProduct(@PathVariable Integer id, Model model) {
model.addAttribute("product", productService.getProductById(id));
return "productshow";
}
// Afficher le formulaire de modification du Product
@RequestMapping("product/edit/{id}")
public String edit(@PathVariable Integer id, Model model) {
model.addAttribute("product", productService.getProductById(id));
return "productform";
}
/**
* New product.
*
* @param model
* @return
*/
@RequestMapping("product/new")
public String newProduct(Model model) {
model.addAttribute("product", new Product());
return "productform";
}
/**
* Save product to database.
*
* @param product
* @return
*/
@RequestMapping(value = "product", method = RequestMethod.POST)
public String saveProduct(Product product) {
productService.saveProduct(product);
return "redirect:/product/" + product.getId();
}
/**
* Delete product by its id.
*
* @param id
* @return
*/
@RequestMapping("product/delete/{id}")
public String delete(@PathVariable Integer id) {
productService.deleteProduct(id);
return "redirect:/products";
}
}
ProductService.java
package com.ensat.services;
import com.ensat.entities.Product;
public interface ProductService {
Iterable<Product> listAllProducts();
Product getProductById(Integer id);
Product saveProduct(Product product);
void deleteProduct(Integer id);
}
ProductServiceImpl.java
package com.ensat.services;
import com.ensat.entities.Product;
import com.ensat.repositories.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Product service implement.
*/
@Service
public class ProductServiceImpl implements ProductService {
private ProductRepository productRepository;
@Autowired
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
@Override
public Iterable<Product> listAllProducts() {
return productRepository.findAll();
}
@Override
public Product getProductById(Integer id) {
return productRepository.findOne(id);
}
@Override
public Product saveProduct(Product product) {
return productRepository.save(product);
}
@Override
public void deleteProduct(Integer id) {
productRepository.delete(id);
}
}
这是我的错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method setProductService in com.ensat.controllers.ProductController required a bean of type 'com.ensat.services.ProductService' that could not be found.
Action:
Consider defining a bean of type 'com.ensat.services.ProductService' in your configuration.
我有完整的日志:https://gist.github.com/donhuvy/b918e20eeeb7cbe3c4be4167d066f7fd
这是我的完整源代码 https://github.com/donhuvy/accounting/commit/319bf6bc47997ff996308c890eba81a6fa7f1a93
如何修复错误?
答案 0 :(得分:7)
bean不是由Spring创建的,因为componentScan
属性错过了ProductServiceImpl
所在的包。
此外,@EnableJpaRepositories
缺失。因此,Spring无法连接您的存储库。
@SpringBootApplication
@ComponentScan(basePackages = {"hello","com.ensat.controllers"})
@EntityScan("com.ensat.entities")
应替换为:
@SpringBootApplication
@ComponentScan(basePackages = {"hello","com.ensat.controllers", "com.ensat.services";
})
@EntityScan("com.ensat.entities")
@EnableJpaRepositories("com.ensat.repositories")
它将解决您的问题,但这种做法违背了Spring和Spring Boot的配置优势的惯例。
如果Application
bean类位于父包中,则所有其他类
bean类属于它或它的子包,你不再需要指定这两个注释:
@ComponentScan(basePackages = {"hello","com.ensat.controllers"})
@EntityScan("com.ensat.entities")
<{1>}班级中的。
例如,在@SpringBootApplication
包中移动Application
并将所有bean移动到此包或其子包中都将解决配置问题并减轻配置。 / p>
com.ensat
为什么?
因为package com.ensat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
...
}
已包含它们(及更多):
@SpringBootApplication
但是它使用当前类的包作为@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
值来发现bean /实体/存储库等...
文件提到了这一点。
Here:
许多Spring Boot开发人员总是对其主类进行注释 使用@Configuration,@ EnableAutoConfiguration和@ComponentScan。 由于这些注释经常被一起使用(特别是如果 你遵循上面的最佳实践),Spring Boot提供了一个 方便的@SpringBootApplication替代方案。
@SpringBootApplication注释等同于使用 @Configuration,@ EnableAutoConfiguration和@ComponentScan与他们的 默认属性
此处讨论basePackage
77.3 Use Spring Data repositories point提供的实体发现:
Spring Boot试图猜测你的@Repository的位置 定义,基于它找到的@EnableAutoConfiguration。得到 更多控件,使用@EnableJpaRepositories注释(来自Spring 数据JPA)。
答案 1 :(得分:0)
我遇到了这个错误,我花了一整个下午来弄明白。我已经检查了每个 stackoverflow 帖子, spring.io 文档,与此问题相关的github问题,并且没有一个答案可以解决错误。
总之,我尝试过:
鉴于我有两个存储库,其中没有一个被 @ComponentScan 或 @EntityScan 注释识别。总而言之,我无法用它们实例化或执行任何操作。
对我来说诀窍是什么,如果你已经筋疲力尽,我建议你做什么呢
有时调试这些应用程序会非常痛苦。我有我的份额。我希望它有所帮助!