Rozważ zdefiniowanie komponentu bean typu „pakiet” w swojej konfiguracji [Spring-Boot]


110

Otrzymuję następujący błąd:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method setApplicant in webService.controller.RequestController required a bean of type 'com.service.applicant.Applicant' that could not be found.


Action:

Consider defining a bean of type 'com.service.applicant.Applicant' in your configuration.

Nigdy wcześniej nie widziałem tego błędu, ale to dziwne, że @Autowire nie działa. Oto struktura projektu:

Interfejs kandydata

public interface Applicant {

    TApplicant findBySSN(String ssn) throws ServletException;

    void deleteByssn(String ssn) throws ServletException;

    void createApplicant(TApplicant tApplicant) throws ServletException;

    void updateApplicant(TApplicant tApplicant) throws ServletException;

    List<TApplicant> getAllApplicants() throws ServletException;
}

ApplicantImpl

@Service
@Transactional
public class ApplicantImpl implements Applicant {

private static Log log = LogFactory.getLog(ApplicantImpl.class);

    private TApplicantRepository applicantRepo;

@Override
    public List<TApplicant> getAllApplicants() throws ServletException {

        List<TApplicant> applicantList = applicantRepo.findAll();

        return applicantList;
    }
}

Teraz powinienem mieć tylko Autowire Applicant i mieć dostęp do niego, jednak w tym przypadku nie działa, gdy dzwonię w moim @RestController:

@RestController
public class RequestController extends LoggingAware {

    private Applicant applicant;

    @Autowired
    public void setApplicant(Applicant applicant){
        this.applicant = applicant;
    }

    @RequestMapping(value="/", method = RequestMethod.GET)
    public String helloWorld() {

        try {
            List<TApplicant> applicantList = applicant.getAllApplicants();

            for (TApplicant tApplicant : applicantList){
                System.out.println("Name: "+tApplicant.getIndivName()+" SSN "+tApplicant.getIndSsn());
            }

            return "home";
        }
        catch (ServletException e) {
            e.printStackTrace();
        }

        return "error";
    }

}

------------------------ AKTUALIZACJA 1 -----------------------

dodałem

@SpringBootApplication
@ComponentScan("module-service")
public class WebServiceApplication extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebServiceApplication.class);
    }

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

}

i błąd zniknął, ale nic się nie stało. Jednak kiedy skomentowałem wszystko, czym zajmowałem Applicantsię RestControllerprzed dodaniem, @ComponentScan()byłem w stanie zwrócić ciąg znaków UI, co oznacza, że RestControllerdziałałem, teraz jest pomijany. Teraz jestem brzydka Whitelabel Error Page.

--------------------- AKTUALIZACJA 2 --------------------------- ---

Dodałem podstawowe opakowanie fasoli, na którą narzekał. Błąd odczytuje:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method setApplicantRepo in com.service.applicant.ApplicantImpl required a bean of type 'com.delivery.service.request.repository.TApplicantRepository' that could not be found.


Action:

Consider defining a bean of type 'com.delivery.request.request.repository.TApplicantRepository' in your configuration.

dodałem @ComponentScan

@SpringBootApplication
@ComponentScan({"com.delivery.service","com.delivery.request"})
public class WebServiceApplication extends SpringBootServletInitializer {

    @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebServiceApplication.class);
    }

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

}

---------------------------- Aktualizacja 3 -------------------- -

dodanie:

@SpringBootApplication
@ComponentScan("com")
public class WebServiceApplication extends SpringBootServletInitializer {

wciąż narzeka na moją ApplicantImplklasę, w której @Autowiresmam repozytorium TApplicantRepository.


Gdzie jest plik kontekstu Twojej aplikacji? Jeśli nie masz, należy wziąć pod uwagę, aby dać wiosna jakieś podpowiedzi z adnotacjami jak @ComponentScan zarabiania wszystkie ziarna dostępne.
— Mario Santini

@MarioSantini, zobacz aktualizację 1
— Mike3355

Zakładam, że po każdej aktualizacji były zmiany w błędach? Jeśli to możliwe, opublikuj strukturę projektu i dzienniki błędów / śledzenie stosu w każdym przypadku. Lepiej jest wiedzieć „Dlaczego” ten błąd wystąpił, niż „coś” spowodowało, że błąd zniknął. Będzie pomocny także dla innych osób, które napotkają podobny problem.
— Ameen.M

Odpowiedzi:


202

Może to być spowodowane tym, że projekt został podzielony na różne moduły.

@SpringBootApplication
@ComponentScan({"com.delivery.request"})
@EntityScan("com.delivery.domain")
@EnableJpaRepositories("com.delivery.repository")
public class WebServiceApplication extends SpringBootServletInitializer {

5
Chłodny. Mój projekt jest podzielony na kilka modułów. ComponentScan rozwiązał mój problem!
— kholofelo Maloma

Adnotacja ComponentScan rozwiązała mój problem, ale @EnableAutoConfiguration nie działa
— jpl

W rzeczywistości EnableAutoConfiguration niejawnie definiuje podstawowy „pakiet wyszukiwania” dla niektórych elementów, a użycie pakietu głównego umożliwia również użycie adnotacji ComponentScan bez konieczności określania atrybutu basePackage. Adnotacja @SpringBootApplication może zostać użyta, jeśli twoja główna klasa znajduje się w pakiecie głównym
— jpl

1
To rozwiązanie pomogło mi z tym błędem w wersji 2.0.4
— manu muraleedharan

2
Tak, wynika to z faktu, że projekt został podzielony na różne moduły. @EntityScani @EnableJpaRepositoriesprzy odpowiednich nazwach pakietów zadziałało dla mnie.
— Adi Sivasankaran

52

Jest szansa ...
Możecie być brakuje @Service, @Repositoryadnotacja na swoich odpowiednich klas implementacyjnych.


2
To powinna być przyjęta odpowiedź, prosta i konkretna. Dziękuję Ci.
— Nightfury

1
Pracował dla mnie. Dzięki.
— Okafor T Kosiso

1
Dziękuję, brakowało mi adnotacji
— @Repository

1
Tak, to powinna być odpowiedź. Powyższe odpowiedzi zakładają po prostu, że skanowanie się nie powiodło, co jest błędne.
— Sumit Badsara

48

Wygląda na to, że Twoja klasa kandydata nie została przeskanowana. Domyślnie @SpringBootApplicationprzeskanowane zostaną wszystkie pakiety zaczynające się od katalogu głównego jako klasy, do której wstawiłeś.

załóżmy, że Twoja mainklasa „WebServiceApplication” znajduje się w „ com.service.something”, a następnie wszystkie komponenty, które należą do kategorii „ com.service.something”, są skanowane i „ com.service.applicant” nie będą skanowane.

Możesz albo zrestrukturyzować swoje pakiety, aby „WebServiceApplication” znalazło się w pakiecie głównym, a wszystkie inne składniki stały się częścią tego pakietu głównego. Lub możesz dołączyć@SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"}) itp. Tak, aby „WSZYSTKIE” komponenty były skanowane i inicjalizowane w pojemniku sprężyny.

Aktualizacja na podstawie komentarza

Jeśli masz wiele modułów, które są zarządzane przez maven / gradle, wszystkie potrzeby wiosny to pakiet do skanowania. Nakazujesz spring przeskanować „com.module1” i masz inny moduł, którego nazwa pakietu głównego to „com.module2”, te komponenty nie zostaną przeskanowane. Możesz nawet nakazać Springowi skanowanie „com”, które następnie przeskanuje wszystkie komponenty w „ com.module1.” i „ com.module2.”


Mój projekt to struktura to różne moduły. Na przykład usługi będą miały swój własny moduł i build.gradle. Te build.gradlenazwy modułów są dodawane do dependenciesmodułu za pomocą metody main. Dlatego kiedy zobaczyłeś @ComponentScan("module-service"), pomyślałem, że to zadziała. Jednak w środku module-servicema jedno opakowanie. Więc moje pytanie, jak by to wyglądało? Czy mam tylko nazwać nazwę pakietu lub nazwę modułu, czy w jakiś sposób oba?
— Mike3355

Nie ma znaczenia, czy pakiety są podzielone na różne moduły. Opakowania, w których mają być skanowane komponenty, należy określić jako sprężynowe. Możesz podać wszystkie nazwy pakietów „root” wszystkich swoich modułów w atrybucie „scanBasePackages”. I wszystkie „pakiety”, o których należy wspomnieć, a nie moduły.
— Ameen.M

Zrobiłem co powiedziałeś i błąd zniknął ale tylko narzekać na kolejną paczkę. Oczywiście dodałem go do listy, ale nie zniknie. Zaimplementowałem to w ten sposób:@SpringBootApplication(scanBasePackages= {"com.delivery.service","com.delivery.request"})
— Mike3355

Właśnie to zrobiłem @SpringBootApplication(scanBasePackages= "com")i narzeka na repozytorium JPA. Dziękuję Ci bardzo. Nie wiedziałem, że spring przeskanuje wszystkie pakiety zaczynające się od „com”, jeśli wykonasz powyższe.
— Mike3355

23

Zasadniczo dzieje się tak, gdy masz aplikację klasową w „innym pakiecie”. Na przykład:

com.server
 - Applicacion.class (<--this class have @ComponentScan)
com.server.config
 - MongoConfig.class 
com.server.repository
 - UserRepository

Rozwiązuję z tym problem w Application.class

@SpringBootApplication
@ComponentScan ({"com.server", "com.server.config"})
@EnableMongoRepositories ("com.server.repository") // this fix the problem

Innym mniej eleganckim sposobem jest: umieszczenie wszystkich klas konfiguracyjnych w tym samym pakiecie.


2
W rzeczywistości nie musisz określać @ComponentScanw powyższym scenariuszu. Ponieważ twój Application.class(który ma @SpringBootApplicationadnotację) jest umieszczony, w com.serverktórym i tak jest korzeń zarówno dla, com.server.configjak i com.server.repository.
— Ameen.M

@ Ameen.M To jest moje dokładne pytanie, dlaczego nadal nie można go rozwiązać i dlaczego wymaga jawnego skanowania w celu użycia repozytoriów mongo @EnableMongoRepositories?
— Karthikeyan

10

W moim przypadku popełniłem straszny błąd. włożyłem@Service się do interfejsu serwisowego.

Aby to naprawić, położyłem @Servicena implementację plik serwisowy i u mnie zadziałało.


Dla mnie to samo. Dzięki
— Manta

7

Jeśli fasola znajduje się w tym samym pakiecie, w którym jest @Autowired, nigdy nie spowoduje takiego problemu. Jednak ziarna nie są domyślnie dostępne z różnych pakietów. Aby rozwiązać ten problem, wykonaj następujące kroki:

  1. Zaimportuj następujące elementy w swojej głównej klasie:
    import org.springframework.context.annotation.ComponentScan;
  2. dodaj adnotację do swojej głównej klasy:
@ComponentScan(basePackages = {"your.company.domain.package"})
public class SpringExampleApplication {

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

5

Myślę, że możesz to uprościć, dodając adnotacje do repozytorium z @Repository, a następnie zostanie ono włączone automatycznie przez Spring Framework.


4

W moim przypadku te dwie opcje zadziałały.

  1. in //@ComponentScan ({"myapp", "myapp.resources","myapp.services"}) obejmuje również pakiet, który zawiera Application.classna liście, lub

  2. Po prostu dodaj @EnableAutoConfiguration; automatycznie rozpoznaje wszystkie fasolki wiosenne.


3

Może się to również zdarzyć, jeśli używasz Lombok i dodasz pola @RequiredArgsConstructori @NonNulldla, ale niektóre z twoich pól nie mają zostać wstrzyknięte w konstruktorze. To tylko jedna z możliwości uzyskania tego samego błędu.

parametr 0 wymagał komponentu bean typu MissingBeanName, którego nie można znaleźć

W moim przypadku błąd powiedział mi, w jakim kontrolerze jest problem, po usunięciu @NonNullaplikacji wystartowała dobrze


3

Napotkałem znany problem w moim wielomodułowym projekcie Mavena ze Spring Boot 2. Problem dotyczył nazewnictwa moich pakietów w modułach podrzędnych Mavena.

@SpringBootApplication zawiera wiele komponentów, takich jak - @ComponentScan, @EnableAutoConfiguration, jpa-repositories, json-serialization i tak dalej. I umieszcza @ComponentScan w pakiecie kosmicznym com. *******. Ta część pakietu com. *******. Przestrzeń musi być wspólna dla wszystkich modułów.

Aby to naprawić:

  1. Należy zmienić nazwy wszystkich pakietów modułów. Innymi słowy, trzeba było mieć we wszystkich pakietach we wszystkich modułach Mavena - tę samą część nadrzędną. Na przykład - com. *******. Space
  2. Musisz także przenieść punkt wejścia do tego pakietu - spacja com. *******

2

Szukałem odpowiedzi online, ale wydaje mi się, że nie ma jednego właściwego rozwiązania w moim przypadku: na samym początku wszystko działa tak:

@Slf4j
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GroupService {
    private Repository repository;
    private Service service;
}

Następnie próbuję dodać mapę do buforowania czegoś i wygląda to tak:

@Slf4j
@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GroupService {
    private Repository repository;
    private Service service;
    Map<String, String> testMap;
}

Bum!

Description:

Parameter 4 of constructor in *.GroupService required a bean of type 'java.lang.String' that could not be found.


Action:

Consider defining a bean of type 'java.lang.String' in your configuration.

Usunąłem @AllArgsConstructor(onConstructor = @__(@Autowired))i dodać @Autowireddo siebie repositoryi servicewyjątkiem Map<String, String>. Po prostu działa jak wcześniej.

@Slf4j
@Service
public class SecurityGroupService {
    @Autowired
    private Repository repository;
    @Autowired
    private Service service;
    Map<String, String> testMap;
}

Mam nadzieję, że to może być pomocne.


2

U mnie zadziałało po dodaniu poniższej adnotacji w aplikacji:

@ComponentScan({"com.seic.deliveryautomation.mapper"})

Otrzymałem poniższy błąd:

„parametr 1 konstruktora w wymaganym komponencie bean typu mapper, którego nie można znaleźć:



2

Ten błąd pojawi się również, jeśli przypadkowo zdefiniujesz tę samą ziarno w dwóch różnych klasach. To mi się przydarzyło. Komunikat o błędzie był mylący. Po usunięciu dodatkowego ziarna problem został rozwiązany.


1
@SpringBootApplication
@MapperScan("com.developer.project.mapper")

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

1

Może się tak zdarzyć, jeśli klasa @Service jest oznaczona jako abstrakcyjna.


1

Jeśli zależność Twojej klasy jest zarządzana przez Spring, ten problem może wystąpić, jeśli zapomnimy dodać domyślnego / pustego konstruktora arg w naszej klasie POJO.


1

To może komuś pomóc. Miałem ten sam problem, ten sam komunikat o błędzie, to samo wszystko. Próbowałem rozwiązań z innych odpowiedzi, ale nie pomogło, dopóki nie zdałem sobie sprawy, że fasola, której używam, ma taką samą nazwę, jak ta, która jest w rzeczywistości autowredowana. Stało się to w trakcie refaktora, więc musiałem zmienić nazwę klasy, co dało wynik pozytywny. Twoje zdrowie


1

Miałem ten sam problem. Repozytorium Mongo DB zostało zidentyfikowane przez Spring boot, ale nie tworzyło Bean dla interfejsu repozytorium, który rozszerzył repozytorium mongo.

Problemem w moim przypadku była nieprawidłowa specyfikacja wersji w maven pom dla "wiosna + mango". Zmieniłem identyfikator grupy artefaktu i wszystko działało jak magia. adnotacje nie są potrzebne, bo o wszystko zadbał sprężynowy but.

Podczas rozwiązywania problemu szukałem rozwiązań w całej sieci i zdałem sobie sprawę, że ten problem jest w rzeczywistości związany z konfiguracją projektu, każdy, kto ma do czynienia z tym problemem, powinien najpierw sprawdzić konfigurację swojego projektu i włączyć debugowanie od wiosny, aby uzyskać więcej informacji na temat niepowodzenia i zwrócić szczególną uwagę na gdzie dokładnie w procesie tworzenie się nie powiodło.


0

W moim przypadku ten błąd pojawia się, ponieważ mój import był nieprawidłowy, na przykład za pomocą sprężyny import pojawia się automatycznie:

import org.jvnet.hk2.annotations.Service;

ale potrzebowałem:

import org.springframework.stereotype.Service;

0

Miałem przypadek, w którym muszę wstrzyknąć RestTemplate do klasy usług. Jednak RestTemplate nie może zostać odebrany przez klasę usługi. To, co zrobiłem, to utworzenie klasy opakowania w tym samym pakiecie co główna aplikacja i oznaczenie opakowania jako Component i automatyczne połączenie tego komponentu w klasie usługi. Problem rozwiązany. mam nadzieję, że to również działa dla Ciebie


0

Mój błąd polegał na tym, że uwzględniłem:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

zamiast:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

0

Myślę, że brakuje Ci adnotacji @Bean w kontrolerze żądań

Dodaj Bean do swojego pliku. To rozwiązało mój problem.
Otrzymałem to rozwiązanie, gdy uczyłem się Spring Boot z tutorialspoint

private Applicant applicant;

@Bean 
public Applicant applicant() { 
    return new Applicant(); 
}

0

Dodanie zależności Spring Boot Data JPA Starter rozwiązało problem.

Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

Gradle

compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.2.6.RELEASE'

Możesz też przejść bezpośrednio tutaj


To faktycznie nie ma zastosowania w tym przypadku. Pyta o szczegóły połączenia z bazą danych (nie udało się skonfigurować DataSource: atrybut „url” nie został określony i nie można skonfigurować wbudowanego źródła danych). W sytuacji, gdy chcę przetestować ręcznie bez interakcji z bazą danych, to nie zadziała.
— Thomas Okonkwo

0

Jeśli używasz interface, możesz rozszerzyć CrudRepository<Applicant,Long>o @Repositoryadnotację.


0

Problem może się również pojawić, gdy używasz na przykład @EnableMongoRepositories(YOUR_MONGO_REPOSITORIES_PACKAGE) a później zmienisz nazwę pakietu lub przeniesiesz go w inne miejsce.

Bardzo często spotykaliśmy się z tym w ramach wielomodułowego projektu maven i wiosennego buta


0

Jest szansa, że próbujesz @autowired z interfejsem przed implementować interfejs.

przykładowe rozwiązanie:

    **HomeController.java**
    class HomeController{

      @Autowired
      UserService userService;
    .....
    }
----------------------------------------------------------------------
    **UserService.java** 
    public interface UserService {
        User findByUsername(String username);
    .....
    }
-----------------------------------------------------------------------
     **UserServiceImpl.java**
     @Service
     public class UserServiceImpl implements UserService{

         public User findByUsername(String username) {
           return userDao.findByUsername(username);
         }
        ....
      }

<i>This is not italic</i>, and [this is not a link](https://example.com)

0

Usuń konfigurację typu adnotacji, taką jak @Service, z metody uruchamiania wątku.

@Service, @Component

0

Spróbuj skonfigurować strukturę projektu, jak podano poniżej:

Umieść wszystkie repozytoria, usługi, pakiety w pakiecie podrzędnym pakietu głównego:

package com.leisure.moviemax;  //Parent package
        
@SpringBootApplication
@PropertySource(value={"classpath:conf.properties"})
    
public class MoviemaxApplication implements CommandLineRunner {
        
package com.leisure.moviemax.repo; //child package

@Repository
public interface UsrRepository extends JpaRepository<UserEntity,String> {

0

Przypominamy, że wiosna nie skanuje świata, używa skanowania ukierunkowanego, co oznacza wszystko, co znajduje się pod opakowaniem, w którym przechowywane są pliki springbootapplication. dlatego ten błąd „Rozważ zdefiniowanie komponentu bean typu„ pakiet ”w swojej konfiguracji [Spring-Boot]” może pojawić się, ponieważ masz interfejsy usług w innym pakiecie springbootapplication.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.