Проблема с передачей интерфейса в конструктор контроллера - PullRequest
0 голосов
/ 17 февраля 2019

Я новичок в весне.Ниже проблема, с которой я сталкиваюсь.Пожалуйста, помогите.

При запуске инструментов разработчика я получаю следующую ошибку

Параметру 0 конструктора в tacos.web.DesignTacoController требуется bean-компонент типа 'taco.data.IngredientRepository', которыйне может быть найден.

Действие:

Попробуйте определить bean-компонент типа 'taco.data.IngredientRepository' в вашей конфигурации.

IngredientRepository.java

package taco.data;

import tacos.Ingredient;

public interface IngredientRepository {

    Iterable<Ingredient> findAll();

    Ingredient findOne(String id);

    Ingredient save(Ingredient ingredient);

}

JdbcIngredientRepository.java

package taco.data;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import tacos.Ingredient;

@Repository
public class JdbcIngredientRepository implements IngredientRepository {


    private JdbcTemplate jdbc;

    @Autowired
    public JdbcIngredientRepository (JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    @Override
    public Iterable<Ingredient> findAll() {
        return jdbc.query("SELECT ID, NAME, TYPE FROM INGREDIENT", this::mapRowToIngredient);
    }

    @Override
    public Ingredient findOne(String id) {
        return jdbc.queryForObject("SELECT ID, NAME, TYPE FROM INGREDIENT WHERE ID=?", this::mapRowToIngredient, id);
    }

    @Override
    public Ingredient save(Ingredient ingredient) {
        jdbc.update("INSERT INTO INGREDIENT VALUES (?,?,?)", ingredient.getId(), ingredient.getId(), ingredient.getType());
        return ingredient;
    }

    private Ingredient mapRowToIngredient(ResultSet rs, int rowNum)
            throws SQLException {
        return new Ingredient(rs.getString("id"), rs.getString("name"), Ingredient.Type.valueOf(rs.getString("type")));
    }

}

DesignTacoController.java

package tacos.web;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

import lombok.extern.slf4j.Slf4j;
import taco.data.IngredientRepository;
import tacos.Ingredient;
import tacos.Ingredient.Type;
import tacos.Taco;

@Slf4j
@Controller
@RequestMapping("/design")
@SessionAttributes("order")
public class DesignTacoController {

    private final IngredientRepository ingredientRepo;

    @Autowired
    public DesignTacoController(IngredientRepository ingredientRepo) {
        this.ingredientRepo = ingredientRepo;
    }

    @GetMapping
    public String showDesignForm(Model model) {


        List<Ingredient> ingredients = new ArrayList<>();
        ingredientRepo.findAll().forEach(i -> ingredients.add(i));

        Type[] types = Ingredient.Type.values();
        for (Type type : types) {
            model.addAttribute(type.toString().toLowerCase(),
            filterByType(ingredients, type));
        }
        model.addAttribute("design", new Taco());
        return "design";

    }

    @PostMapping
    public String processDesign(@Valid Taco design, Errors errors) {
        if(errors.hasErrors()) {
            return "design";
        }

        log.info("Processing Design " + design);

        return "redirect:/orders/current";
    }

    public List<Ingredient> filterByType (List<Ingredient> actualList, Type type) {
        return actualList.stream().filter(ingredient -> type.equals(ingredient.getType())).collect(Collectors.toList());
    }
}

Класс начальной загрузки SpringBoot

package tacos;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
public class TacoCloudApplication {

    public static void main(String[] args) {
        SpringApplication.run(TacoCloudApplication.class, args);
    }

}

Ссылка на проект Github

1 Ответ

0 голосов
/ 17 февраля 2019

Проблема

TacoCloudApplication не видит ни одного @Component (@Repository - @Component), определенного вне пакета tacos.

С Spring Boot Reference Guide :

Одну аннотацию @SpringBootApplication можно использовать для включения этих трех функций, а именно:

  • @EnableAutoConfiguration: включитьМеханизм автоконфигурации Spring Boot
  • @ComponentScan: включить @Component сканирование в пакете, в котором находится приложение
  • @Configuration: разрешить регистрацию дополнительных биновв контексте или импортировать дополнительные классы конфигурации

Он видит только @Component s, определенные ниже tacos пакета

Решение

Переместить JdbcIngredientRepository к пакету, начинающемуся с tacos.

, чтобы структура вашего приложения стала:

└── tacos
    ├── data
    │   ├── IngredientRepository.java
    │   └── JdbcIngredientRepository.java
    ├── Ingredient.java
    ├── Order.java
    ├── TacoCloudApplication.java
    ├── Taco.java
    └── web
    ├── DesignTacoController.java
    ├── OrderController.java
    └── WebConfig.java

Или добавьте

@ComponentScans(
    value = {
        @ComponentScan("tacos"),
        @ComponentScan("taco")
    }
)

к классу TacoCloudApplication.

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...