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.

Mike3355
źródło
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 {
Mike3355
źródło
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.

CodeWorld
źródło
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.

Ameen.M
źródło
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.

Carlos Marcano
źródło
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.

Mohammad Falahi
źródł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);
    }
}
ASHWANI PANDEY
źródło
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.

Tushar Saha Chowdhury
źródło
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.

Sriharsha grv
źródło
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

Dawid Gorczyca
źródło
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. *******
alexis_druzik
źródło
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.

Hearen
źródło
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źć:

Uwielbiam Kumara
źródło
2

Adnotacja @Configuration po prostu rozwiąże błąd

oludamilare olukotun
źródło
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.

Ross Mills
źródło
1
@SpringBootApplication
@MapperScan("com.developer.project.mapper")

public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
programista07
źródło
1

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

Ariel
źródło
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.

Arif Khan
źródło
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

Staxx
źródło
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.

user13650952
źródł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;
Washington da Silva
źródło
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

user11976602
źródło
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>
user1441323
źródło
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(); 
}
user3709901
źródło
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

Johny Thomas Kariath
źródło
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ę.

zawhtut
źródło
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

redoff
źródło
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)
biddut
źródło
0

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

@Service, @Component
Sandun Susantha
źródło
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> {
Barani r
źródło
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.

popcornw
źródło