[英]Consider defining a bean of type 'com.ensat.services.ProductService' in your configuration
I have 我有
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 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 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 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);
}
}
This is my error: 这是我的错误:
***************************
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.
I have full log: https://gist.github.com/donhuvy/b918e20eeeb7cbe3c4be4167d066f7fd 我有完整的日志: https : //gist.github.com/donhuvy/b918e20eeeb7cbe3c4be4167d066f7fd
This is my full source code https://github.com/donhuvy/accounting/commit/319bf6bc47997ff996308c890eba81a6fa7f1a93 这是我的完整源代码https://github.com/donhuvy/accounting/commit/319bf6bc47997ff996308c890eba81a6fa7f1a93
How to fix error? 如何修复错误?
The bean is not created by Spring since componentScan
attribute misses the package where ProductServiceImpl
is located. bean不是由Spring创建的,因为
componentScan
属性错过了ProductServiceImpl
所在的包。
Besides, @EnableJpaRepositories
is missing. 此外,还缺少
@EnableJpaRepositories
。 So, Spring cannot wire your repository. 因此,Spring无法连接您的存储库。
@SpringBootApplication
@ComponentScan(basePackages = {"hello","com.ensat.controllers"})
@EntityScan("com.ensat.entities")
should be replaced by : 应该替换为:
@SpringBootApplication
@ComponentScan(basePackages = {"hello","com.ensat.controllers", "com.ensat.services";
})
@EntityScan("com.ensat.entities")
@EnableJpaRepositories("com.ensat.repositories")
It will solve your problem but this way of doing defeats the convention over configuration advantage of Spring and Spring Boot. 它将解决您的问题,但这种做法违反了Spring和Spring Boot的配置优势的约定。
If the Application
bean class was located in a parent package which all other bean classes belongs to or to a sub-package of it, you would not need any longer to specify these two annotations : 如果
Application
bean类位于所有其他bean类所属的父包或它的子包中,则不再需要指定这两个注释:
@ComponentScan(basePackages = {"hello","com.ensat.controllers"})
@EntityScan("com.ensat.entities")
in the @SpringBootApplication
class. 在
@SpringBootApplication
类中。
For example, moving Application
in the com.ensat
package and move all your beans in this package or in a child of it will both solve your configuration issues and alleviate your configuration. 例如,在
com.ensat
包中移动Application
并将所有bean移动到此包或它的子包中都将解决配置问题并减轻配置。
package com.ensat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
...
}
Why ? 为什么?
Because the @SpringBootApplication
includes already them (and more) : 因为
@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 {
But that uses the package of the current class as basePackage
value to discover beans/entities/repositories, etc... 但是,它使用当前类的包作为
basePackage
值来发现bean /实体/存储库等...
The documentation refers this point. 文档提到了这一点。
Many Spring Boot developers always have their main class annotated with @Configuration, @EnableAutoConfiguration and @ComponentScan.
许多Spring Boot开发人员总是使用@Configuration,@ EnableAutoConfiguration和@ComponentScan注释其主类。 Since these annotations are so frequently used together (especially if you follow the best practices above), Spring Boot provides a convenient @SpringBootApplication alternative.
由于这些注释经常一起使用(特别是如果您遵循上面的最佳实践),Spring Boot提供了一个方便的@SpringBootApplication替代方案。
The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes
@SpringBootApplication注释等同于使用@ Configuration,@ EnableAutoConfiguration和@ComponentScan及其默认属性
Here it discusses about entities discovery provided by @EnableAutoConfiguration
77.3 Use Spring Data repositories point : 这里讨论
@EnableAutoConfiguration
提供的实体发现77.3使用Spring Data存储库点 :
Spring Boot tries to guess the location of your @Repository definitions, based on the @EnableAutoConfiguration it finds.
Spring Boot会根据找到的@EnableAutoConfiguration尝试猜测@Repository定义的位置。 To get more control, use the @EnableJpaRepositories annotation (from Spring Data JPA).
要获得更多控制,请使用@EnableJpaRepositories批注(来自Spring Data JPA)。
I was experiencing this very error, and it took me a whole afternoon to figure it out. 我遇到了这个错误,我花了整整一个下午才弄清楚。 I have checked every stackoverflow post, spring.io docs, github issue related to this issue, and none of the answers could solve what was wrong.
我已经检查了每个stackoverflow帖子, spring.io docs,与此问题相关的github问题,并且没有一个答案可以解决错误。
In summary, I have tried: 总之,我试过:
Given I had two repositories, none of them was being recognized by
@ComponentScan or @EntityScan annotations.
鉴于我有两个存储库,其中没有一个被@ComponentScan或@EntityScan注释识别。 So in summary, I could not instantiate or perform any actions with them.
总而言之,我无法使用它们实例化或执行任何操作。
What did the trick for me, and what i'd suggest you do if you have exhausted your attempts is 对我来说诀窍是什么,如果你已经筋疲力尽,我建议你做什么呢
Sometimes it can be very painful to debug these applications. 有时调试这些应用程序会非常痛苦。 I have had my share.
我有我的份额。 I hope it helps!
我希望它有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.