Подумайте про те, як у вашій конфігурації визначити боб типу "пакунок" [Spring-Boot]


109

Я отримую таку помилку:

***************************
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.

Я ніколи раніше не бачив цієї помилки, але дивно, що @Autowire не працює. Ось структура проекту:

Інтерфейс заявника

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;
}

Імпульс заявника

@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;
    }
}

Тепер я повинен мати змогу просто автопровідником заявника та мати доступ до нього, проте в цьому випадку він не працює, коли я його закликаю @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";
    }

}

------------------------ ОНОВЛЕННЯ 1 -----------------------

я додав

@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);
    }

}

і помилка пішла, але нічого не сталося. Однак , коли я закомментировать вся справа з Applicantв RestControllerперед додаванням @ComponentScan()я зміг повернути рядок в UI, таким чином , це означає , що я RestControllerпрацював, тепер він пропуск. Я негарна Whitelabel Error Pageзараз.

--------------------- ОНОВЛЕННЯ 2 --------------------------- ---

Я додав базовий пакет квасолі, на який скаржився. Помилка читає:

***************************
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.

я додав @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);
    }

}

---------------------------- Оновлення 3 -------------------- -

додавання:

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

досі скаржиться на мій ApplicantImplклас, на який @Autowiresя репоную TApplicantRepository.


Де ваш контекстний файл програми? Якщо у вас його немає, варто подумати про те, щоб надати Spring навесні з анотаціями, як-от @ComponentScan, щоб зробити всі боби доступними.
Маріо Сантіні

@MarioSantini дивіться оновлення 1
Mike3355

Я припускаю, що після кожного оновлення були зміни в помилках? Якщо можливо, опублікуйте структуру свого проекту, і журнали / стеки помилок у кожному випадку. Краще знати "Чому" ці помилки сталися, а не "щось", що помилка усунулася. Буде корисно і для інших, хто натрапив на подібне питання.
Ameen.M

Відповіді:


201

Це може бути тому, що проект був розбитий на різні модулі.

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

5
Класно. Мій проект розділений на декілька модулів. ComponentScan вирішив мою проблему!
холофело Малома

Анотація ComponentScan вирішує мою проблему, але @EnableAutoConfiguration не
jpl

Насправді EnableAutoConfiguration неявно визначає базовий "пакет пошуку" для певних елементів, а використання кореневого пакету також дозволяє використовувати анотацію ComponentScan без необхідності вказувати атрибут basePackage. І анотацію @SpringBootApplication можна використовувати, якщо ваш основний клас знаходиться в кореневому пакеті
jpl

1
Це рішення допомогло мені з цією помилкою у версії 2.0.4
manu muraleedharan

2
Так, це пов'язано з тим, що проект був розбитий на різні модулі. @EntityScanі @EnableJpaRepositoriesз правильними назвами пакунків працювали на мене.
Аді Сівасанкаран

52

Є шанс ...
Ви , можливо, відсутні @Service, @Repositoryанотація на ваші відповідних класах реалізації.


2
Це має бути прийнята відповідь, проста та чітка. Дякую.
нічна ярмарка

1
Працювали для мене. Дякую.
Окафор Т Косісо

1
Дякую, мені не вистачало анотації
@Repository

1
Так, це має бути відповіддю. Наведені вище відповіді просто припускають, що сканування не вдалося, що неправильно.
Суміт Бадсара

48

Ваш клас заявника не сканується, здається. За замовчуванням всі пакети, починаючи з root, як клас, який ви поставили@SpringBootApplication будуть скановані .

припустимо, що ваш mainклас "WebServiceApplication" знаходиться в " com.service.something", тоді всі компоненти, що підпадають під " com.service.something", скануються, і " com.service.applicant" не буде скановано.

Ви можете реструктурувати ваші пакунки таким чином, що "WebServiceApplication" потрапляє під кореневий пакет, а всі інші компоненти стають частиною цього кореневого пакету. Або ви можете включити@SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"}) тощо, щоб "ВСІ" компоненти були відскановані та ініціалізовані у весняному контейнері.

Оновлення на основі коментаря

Якщо у вас є кілька модулів, якими керує maven / gradle, всі весняні потреби - це пакет для сканування. Ви кажете весною сканувати "com.module1", і у вас є інший модуль, котрий має ім'я кореневого пакета як "com.module2", ці компоненти не будуть скановані. Ви навіть можете сказати весном сканувати "com", який потім сканує всі компоненти в " com.module1." і " com.module2."


Мій проект - це структура різних модулів. Наприклад, послуги матимуть власний модуль та build.gradle. Ці build.gradleназви модулів додаються до dependenciesмодуля основним методом. Тому коли ви побачили @ComponentScan("module-service"), це те, що я думав, спрацює. Однак всередині module-serviceє один пакет. Тож моє запитання, як це виглядатиме? Чи просто я називаю ім'я пакета чи ім'я модуля чи якось обидва?
Mike3355

Не має значення, чи пакети потрапляють у різні модулі. Пакети, в яких слід сканувати компоненти, повинні бути вказані до весни. Ви можете надати всі "root" пакети імена всіх ваших модулів в атрибуті "scanBasePackages" .. І всі його "пакети", які слід згадати, а не модулі.
Ameen.M

Зробив те, що ви сказали і, помилка пішла, але лише поскаржитися на ще один пакет. Природно, я додав його до списку, але він не піде. Я реалізував це так:@SpringBootApplication(scanBasePackages= {"com.delivery.service","com.delivery.request"})
Mike3355

Я щойно це зробив, @SpringBootApplication(scanBasePackages= "com")і він скаржиться на сховища JPA. Велике спасибі. Я не знав, що весна сканує всі пакунки, які починаються з "com", якщо ви зробите вище.
Mike3355

23

В основному це відбувається, коли у вас є додаток для класу в "іншому пакеті". Наприклад:

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

Я вирішую проблему з цим у Application.class

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

Ще один менш елегантний спосіб - вмістити всі класи конфігурації в один пакет.


2
Infact, вам не потрібно вказувати @ComponentScanу наведеному вище сценарії. Тому що ваш Application.class(який має @SpringBootApplicationанотацію) розміщується в com.serverякому, в будь-якому випадку, є коренем як для, так com.server.configі для com.server.repository.
Ameen.M

@ Ameen.MTo моє точне запитання: Чому він все ще не може вирішити і чому для нього потрібне явне сканування для монго репостів @EnableMongoRepositories?
Картікеян

10

У моєму випадку у мене була жахлива помилка. Я ставлюсь @Serviceдо сервісного інтерфейсу.

Щоб виправити це, я ставлю @Serviceна реалізацію сервісний файл, і він працював на мене.


Те саме для мене. Спасибі
Манта

7

Якщо квасоля знаходиться в тій же упаковці, в якій вона є @Autowired, вона ніколи не викличе такої проблеми. Однак квасоля за замовчуванням недоступна з різних пакетів. Щоб вирішити цю проблему, виконайте наступні дії:

  1. Імпортуйте наступне у свій основний клас:
    імпорт org.springframework.context.annotation.ComponentScan;
  2. додайте примітку до основного класу:
@ComponentScan(basePackages = {"your.company.domain.package"})
public class SpringExampleApplication {

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

5

Я думаю, ви можете зробити це спрощеним, анотувавши свій сховище за допомогою @Repository, тоді він буде ввімкнено автоматично Spring Framework.


4

У моєму випадку ці два варіанти спрацювали.

  1. в //@ComponentScan ({"myapp", "myapp.resources","myapp.services"}) включають також пакет , який тримає Application.classв списку, або

  2. Просто додайте @EnableAutoConfiguration; він автоматично розпізнає всі ярі боби.


3

Це також може статися, якщо ви використовуєте Lombok і додаєте поля @RequiredArgsConstructorі @NonNullдля полів, але деякі ваші поля не потрібно вводити в конструктор. Це лише одна з можливостей отримати ту саму помилку.

для параметра 0 потрібен боб типу MissingBeanName, якого неможливо було знайти

У моєму випадку помилка повідомила мені, у чому проблема в контролері, після видалення @NonNullпрограми почалося нормально


3

Я зіткнувся зі знайомою проблемою в своєму багатомодульному проекті Maven з Spring Boot 2. Проблема була пов'язана з іменуванням моїх пакетів у модулях Sub Maven.

@SpringBootApplication інкапсулює багато компонентів, таких як - @ComponentScan, @EnableAutoConfiguration, jpa-сховища, json-серіалізація тощо. І він розміщує @ComponentScan у ком. *******. Космічний пакет. Ця частина пакетів, що містять *******. Простір, повинна бути загальною для всіх модулів.

Для її виправлення:

  1. Вам слід перейменувати всі пакети модулів. Інші слова, які вам довелося мати у всіх пакунках у всіх модулях Maven - одна і та сама батьківська частина. Наприклад - простір ком. *******
  2. Також вам потрібно перенести свою точку входу до цього пакету - простір *******

2

Я шукав відповідь в Інтернеті, але, здається, немає жодного належного рішення моєї справи: На самому початку все працює добре так:

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

Тоді я намагаюся додати карту, щоб щось кешувати, і це стає таким:

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

Бум!

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.

Я видалив @AllArgsConstructor(onConstructor = @__(@Autowired))і додати @Autowiredдля кожного repositoryі , serviceкрім Map<String, String>. Це просто працює, як і раніше.

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

Сподіваюся, це може бути корисним.


2

Це працювало для мене після додавання нижче примітки в додаток:

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

Я отримував помилку нижче:

"Параметр 1 конструктора в потрібному бобі картографа типу, якого неможливо знайти:



2

Ви також отримаєте цю помилку, якщо випадково визначите один і той же боб у двох різних класах. Це сталося зі мною. Повідомлення про помилку було оманливим. Коли я видалив зайву квасолю, питання було вирішено.


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

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


1

Якщо залежність вашого класу керує Spring, ця проблема може виникнути, якщо ми забули додати конструктор аргументів за замовчуванням / порожній аргумент у наш клас POJO.


1

Це може комусь допомогти. У мене була та сама проблема, те саме повідомлення про помилку, те саме. Я спробував рішення з інших відповідей, не допоміг, поки не зрозумів, що квасоля, яку я використовую, має те саме ім'я, що і власне автоподключена. Це сталося посеред рефактора, тому мені довелося перейменувати клас, що призвело позитивно. Ура


1

Я зіткнувся з тим же питанням. Репозиторій DB Mongo був ідентифікований завантажувачем Spring, але він не створював Bean для інтерфейсу сховища, який розширював сховище mongo.

Проблема в моєму випадку - неправильна специфікація версії в maven pom для "весна + манго". Я змінив ідентифікатор групи артефакту, і все це працювало як магія. ніяких анотацій не потрібно, оскільки весняний черевик подбав про все.

Під час вирішення проблеми я весь час шукав рішення в Інтернеті і зрозумів, що ця проблема пов’язана з конфігурацією проекту, кожен, хто стикається з цією проблемою, повинен спочатку перевірити їх налаштування проекту та дозволити налагодження з весни, щоб отримати більш детальну інформацію про помилку і звернути пильну увагу на де саме в процесі створення не вдалося.


0

У моєму випадку ця помилка з’являється через те, що мій імпорт був неправильним, наприклад, використовуючи spring, імпорт автоматично з’являється:

import org.jvnet.hk2.annotations.Service;

але мені потрібно:

import org.springframework.stereotype.Service;

0

У мене був випадок, коли мені потрібно ввести RestTemplate в сервісний клас. Однак шаблон RestTemplate не може бути обраний службовим класом. Що я зробив, це створити клас обгортки під тим самим пакетом, що і основний додаток, і позначити обгортку як компонент та автопроводити цей компонент у клас обслуговування. Проблема вирішена. сподіваємось, що це працює і для вас


0

Моя помилка полягала в тому, що я включив:

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

замість:

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

0

Я думаю, ви не вистачаєте анотації @Bean у своєму RequestController

Додайте Бін у свій файл, це вирішило мою проблему.
Я отримав це рішення, коли я навчався Spring Boot з уроку

private Applicant applicant;

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

0

Додавання даних Spring Boot Data JPA Starter залежності вирішило проблему для мене.

Мейвен

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

Градле

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

Або ви можете піти прямо сюди


Це фактично не стосується в цьому випадку. Це вимагає ввести деталі підключення до бази даних (Не вдалося налаштувати DataSource: атрибут 'url' не вказаний, і жоден вбудований джерело даних не може бути налаштований.) У ситуації, коли я хочу перевірити вручну, не взаємодіючи з базою даних, це не спрацює.
Томас Оконкво

0

Якщо ви використовуєте interfaceви можете поширюється CrudRepository<Applicant,Long>з @Repositoryанотаціями.


0

Випуск також може з’являтися, коли ви використовуєте приклад @EnableMongoRepositories(YOUR_MONGO_REPOSITORIES_PACKAGE) а пізніше ви перейменовували назву пакета або переміщували його в інше місце.

Дуже часто стикаються з цим в рамках багатомодульного проекту Maven та весняного завантаження


0

Існує ймовірність того, що ви намагаєтеся @autowired з інтерфейсом , перш ніж реалізувати інтерфейс.

Приклад рішення:

    **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

Видаліть конфігурацію типу примітки, наприклад @Service, з методу запуску потоку.

@Service, @Component

0

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

Помістіть усі пакети репо, послуги, пакунки в дочірній пакет основного пакету:

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

нагадуючи, що весна не сканує світ, вона використовує цільове сканування, що означає все, що знаходиться в пакеті, де зберігається Springbootapplication. тому ця помилка "Розглянемо визначення типу" пакет "пакета у вашій конфігурації [Spring-Boot]" може з’явитися, оскільки у вас є сервісні інтерфейси в іншому пакеті Springbutapplication.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.