Рассмотрите возможность определения bean-компонента типа package в вашей конфигурации [Spring-Boot]


110

Я получаю следующую ошибку:

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

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

Теперь я должен иметь возможность просто использовать Autowire Applicant и иметь доступ, однако в этом случае он не работает, когда я вызываю его в своем @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, чтобы сделать все bean-компоненты доступными.
Марио Сантини

@MarioSantini, пожалуйста, смотрите обновление 1
Mike3355 02

Полагаю, после каждого обновления были изменения в ошибках? Если возможно, опубликуйте структуру вашего проекта и журналы ошибок / stacktrace в каждом случае. Лучше знать «Почему» возникла эта ошибка, а не «что-то» заставило ошибку исчезнуть. Будет полезно для тех, кто сталкивается с подобной проблемой.
Ameen.M 02

Ответы:


202

Возможно, это связано с тем, что проект разбит на разные модули.

@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
Это должен быть принятый ответ, простой и точный. Спасибо.
nightfury

1
Работал у меня. Спасибо.
Okafor T Kosiso,

1
Спасибо, мне не хватало аннотации
@Repository

1
Да, это должен быть ответ. Приведенные выше ответы просто предполагают, что сканирование не удалось, что неверно.
Сумит Бадсара,

48

Похоже, ваш класс кандидата не просматривается. По умолчанию @SpringBootApplicationбудут просканированы все пакеты, начинающиеся с корневого в качестве класса, в который вы поместили .

предположим, что ваш mainкласс «WebServiceApplication» находится в « com.service.something», тогда все компоненты, подпадающие под « com.service.something», сканируются, а « com.service.applicant» сканироваться не будет.

Вы можете реструктурировать свои пакеты так, чтобы «WebServiceApplication» подпадал под корневой пакет, а все остальные компоненты становились частью этого корневого пакета. Или вы можете включить и @SpringBootApplication(scanBasePackages={"com.service.something","com.service.application"})т. Д., Чтобы «ВСЕ» компоненты сканировались и инициализировались в контейнере spring.

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

Если у вас есть несколько модулей, которыми управляет maven / gradle, все, что нужно Spring, - это пакет для сканирования. Вы говорите Spring просканировать com.module1, и у вас есть другой модуль, имя корневого пакета которого - com.module2, эти компоненты не будут сканироваться. Вы даже можете указать Spring сканировать "com", который затем просканирует все компоненты в " com.module1." и " com.module2."


Мой проект состоит из разных модулей. Например, у сервисов будет свой модуль и build.gradle. Эти build.gradleимена модулей добавляются к dependenciesмодулю с помощью метода main. Поэтому, когда вы увидели @ComponentScan("module-service"), я подумал, что это сработает. Однако внутри module-serviceесть одна упаковка. Итак, мой вопрос, как это будет выглядеть? Я просто назову имя пакета или имя модуля или как-то и то, и другое?
Mike3355 02

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

Сделал то, что вы сказали, и ошибка исчезла, но только пожаловаться на еще один пакет. Естественно я добавил его в список, но он никуда не денется. Я реализовал это так:@SpringBootApplication(scanBasePackages= {"com.delivery.service","com.delivery.request"})
Mike3355 02

Я только что @SpringBootApplication(scanBasePackages= "com")это сделал, и он жалуется на репозиторий JPA. Большое спасибо. Я не знал, что spring просканирует все пакеты, начинающиеся с "com", если вы сделаете это.
Mike3355 02 ноя.2016,

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
Фактически, вам не нужно указывать @ComponentScanв приведенном выше сценарии. Поскольку ваш Application.class(который имеет @SpringBootApplicationаннотацию) помещен в com.serverкоторый в любом случае является корнем для обоих, com.server.configа также com.server.repository.
Ameen.M

@ Ameen.M Это мой точный вопрос, почему он все еще не может решить и почему он требует явного сканирования для использования репозиториев mongo @EnableMongoRepositories?
Картикеян

10

В моем случае у меня была ужасная ошибка. Ставлю @Serviceна сервисный интерфейс.

Чтобы исправить это, я поставил @Serviceреализацию служебного файла и у меня это сработало.


Мне то же. Спасибо
Manta

7

Если bean-компонент находится в том же пакете, что и @Autowired, он никогда не вызовет такой проблемы. Однако по умолчанию bean-компоненты недоступны из разных пакетов. Чтобы решить эту проблему, выполните следующие действия:

  1. Импортируйте в основной класс следующее:
    import 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. in также//@ComponentScan ({"myapp", "myapp.resources","myapp.services"}) включает пакет, содержащий в списке, илиApplication.class

  2. Просто добавьте @EnableAutoConfiguration; он автоматически распознает все весенние бобы.


3

Это также может произойти, если вы используете Lombok и добавляете поля @RequiredArgsConstructorи @NonNullfor, но некоторые из ваших полей не должны вводиться в конструктор. Это только одна из возможностей получить ту же ошибку.

для параметра 0 требуется bean-компонент типа MissingBeanName, который не может быть найден

В моем случае ошибка сообщила мне, в каком контроллере возникла проблема, после удаления @NonNullприложение запустилось нормально


Это была и моя ошибка, за исключением @AllArgsConstructorудаления аннотации и разрешения java создать пустой конструктор, позволяя Spring правильно создавать экземпляр объекта и вводить зависимости.
Кристиан Бартрам

3

Я столкнулся со знакомой проблемой в моем многомодульном проекте Maven с Spring Boot 2. Проблема была связана с именованием моих пакетов в подчиненных модулях Maven.

@SpringBootApplication инкапсулирует множество компонентов, таких как @ComponentScan, @EnableAutoConfiguration, jpa-репозитории, json-сериализация и так далее. И он помещает @ComponentScan в пакет com. *******. Space. Эта часть com. *******. Пространства пакетов должна быть общим для всех модулей.

Чтобы исправить это:

  1. Вам следует переименовать все пакеты модулей. Другими словами, вы должны были иметь во всех пакетах всех модулей Maven одну и ту же родительскую часть. Например - com. *******. Пробел
  2. Также вам нужно переместить точку входа в этот пакет - com. *******. Space

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 конструктора в требовал bean-компонент сопоставителя типов, который не может быть найден:



2

Вы также получите эту ошибку, если случайно определите один и тот же компонент в двух разных классах. Это случилось со мной. Сообщение об ошибке вводило в заблуждение. Когда я удалил лишний компонент, проблема была решена.


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

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

1

Это может произойти, если класс @Service помечен как абстрактный.


1

Если зависимость вашего класса управляется Spring, эта проблема может возникнуть, если мы забыли добавить конструктор по умолчанию / пустой arg внутри нашего класса POJO.


1

Это может кому-нибудь помочь. У меня была такая же проблема, такое же сообщение об ошибке, все то же самое. Я пробовал решения из других ответов, не помогло, пока не понял, что бин, который я использую, имеет то же имя, что и тот, который на самом деле был автоматически подключен. Произошло это в разгар рефакторинга, поэтому пришлось переименовать класс, что положительно. Ура


1

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

В моем случае проблема заключалась в неправильной спецификации версии в maven pom для "spring + mango". Я изменил идентификатор группы артефакта, и все заработало как по волшебству. никаких аннотаций не требуется, так как Spring boot позаботился обо всем.

Во время решения проблемы я искал решения по всей сети и понял, что эта проблема на самом деле связана с конфигурацией проекта, любой, кто сталкивается с этой проблемой, должен сначала проверить настройку своего проекта и включить отладку с весны, чтобы получить более подробную информацию о сбое и обратить пристальное внимание на где именно в процессе создание не удалось.


0

В моем случае эта ошибка возникает из-за того, что мой импорт был неправильным, например, при использовании spring импорт автоматически появляется:

import org.jvnet.hk2.annotations.Service;

но мне нужно было:

import org.springframework.stereotype.Service;

0

У меня был случай, когда мне нужно было ввести RestTemplate в класс обслуживания. Однако RestTemplate не может быть получен классом обслуживания. Я создал класс-оболочку в том же пакете, что и основное приложение, и пометил оболочку как Component и автоматически подключил этот компонент к классу обслуживания. Задача решена. надеюсь, это также сработает для вас


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

Добавьте Bean в свой файл, это решило мою проблему.
Я получил это решение, когда изучал Spring Boot из учебной точки.

private Applicant applicant;

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

0

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

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'

Или вы можете пойти прямо сюда


На самом деле это не применимо в данном случае. Он запрашивает сведения о подключении к базе данных (не удалось настроить источник данных: атрибут «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

Попробуйте настроить структуру проекта, как показано ниже:

Поместите все репо, сервисы, пакеты в дочерний пакет основного пакета:

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

Напоминаем, что Spring не сканирует мир, он использует целевое сканирование, то есть все в пакете, где хранится приложение springboot. поэтому эта ошибка «Рассмотрите возможность определения bean-компонента типа 'package' в вашей конфигурации [Spring-Boot]» может появиться из-за того, что у вас есть интерфейсы служб в другом пакете springbootapplication.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.