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.