gpt4 book ai didi

java - 考虑在您的配置中定义类型为 'com.ensat.services.ProductService' 的 bean

转载 作者:行者123 更新时间:2023-12-02 08:48:36 25 4
gpt4 key购买 nike

我有

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

如何修复错误?

最佳答案

该 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")

@SpringBootApplication类中。

例如,将 Application 移至 com.ensat 包中,并将所有 Bean 移至该包或其子包中,既可以解决您的配置问题,又可以缓解您的配置。

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 {

但是它使用当前类的包作为basePackage值来发现bean/实体/存储库等...

文档提到了这一点。

Here :

Many Spring Boot developers always have their main class annotated with @Configuration, @EnableAutoConfiguration and @ComponentScan. Since these annotations are so frequently used together (especially if you follow the best practices above), Spring Boot provides a convenient @SpringBootApplication alternative.

The @SpringBootApplication annotation is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default attributes

这里讨论了@EnableAutoConfiguration提供的实体发现77.3 Use Spring Data repositories point :

Spring Boot tries to guess the location of your @Repository definitions, based on the @EnableAutoConfiguration it finds. To get more control, use the @EnableJpaRepositories annotation (from Spring Data JPA).

关于java - 考虑在您的配置中定义类型为 'com.ensat.services.ProductService' 的 bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40451227/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com