Spring @ComponentScan не обнаруживает REST-контроллер - PullRequest
3 голосов
/ 29 июня 2019

После поиска различных похожих вопросов в StackOverflow я определил, что большинство людей, страдающих от этой проблемы, не сканируют должным образом модуль, в котором живет их контроллер.Некоторые решения требуют объединения файлов, которые должны быть отсканированы, в тот же модуль, что и приложение (которое работает), но я не хочу перемещать ни один из моих файлов .java.Вместо этого я хотел бы заставить @ComponentScan работать.

У меня есть следующая структура проекта

Project
      |
      settings.gradle
      build.gradle
      module1
            |
            src/main/java/com.test.application
            |                                |
            |                                Application.java
            |                                SwaggerConfig.java
            build.gradle
      module2
            |
            src/main/java/com.test.service
            |                            |
            |                            Service.java
            |                            Controller.java
            build.gradle

Application.java

@SpringBootApplication
@ComponentScan("com.test")
public class Application {

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

Обратите внимание, что я сканирую com.test в моем компонентном сканировании.В документации @ ComponentScan (или в StackOverflow) не найдено ничего, что указывало бы на неправильное использование @ComponentScan.

Controller.java

@RestController
@RequestMapping("/test")
public class GearParsingController {
  private SomeService someService;

  @Autowired
  public SomeController(SomeService someService) {
    this.someService = someService;
  }

  @GetMapping("/path")
  public ResponseEntity<String> getSomeService() {
    return new ResponseEntity<String>("Default message", HttpStatus.OK);
  }
}

Проект build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE")
    }
}

subprojects {
    repositories {
        mavenCentral()
    }

    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
}

module1 build.gradle

dependencies {
    implementation project(':module2')

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.6.RELEASE'
}

module2 build.gradle

dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.6.RELEASE'

    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0-RC2'
}

Когда я пытаюсь получить доступ к своим конечным точкам в localhost:8080/test/path, меня встречают:

{
    "timestamp": "2019-06-29T19:19:52.275+0000",
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/test/path"
}

При запуске программы в режиме отладки мне даютследующий вывод:

2019-06-29 13:58:58.345  INFO 8272 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-06-29 13:58:58.387  INFO 8272 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-06-29 13:58:58.387  INFO 8272 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-06-29 13:58:58.522  INFO 8272 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-06-29 13:58:58.522 DEBUG 8272 --- [           main] o.s.web.context.ContextLoader            : Published root WebApplicationContext as ServletContext attribute with name [org.springframework.web.context.WebApplicationContext.ROOT]
2019-06-29 13:58:58.522  INFO 8272 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1786 ms
2019-06-29 13:58:58.544 DEBUG 8272 --- [           main] o.s.b.w.s.ServletContextInitializerBeans : Mapping filters: characterEncodingFilter urls=[/*], hiddenHttpMethodFilter urls=[/*], formContentFilter urls=[/*], requestContextFilter urls=[/*]
2019-06-29 13:58:58.545 DEBUG 8272 --- [           main] o.s.b.w.s.ServletContextInitializerBeans : Mapping servlets: dispatcherServlet urls=[/]
2019-06-29 13:58:58.583 DEBUG 8272 --- [           main] o.s.b.w.s.f.OrderedRequestContextFilter  : Filter 'requestContextFilter' configured for use
2019-06-29 13:58:58.583 DEBUG 8272 --- [           main] .s.b.w.s.f.OrderedHiddenHttpMethodFilter : Filter 'hiddenHttpMethodFilter' configured for use
2019-06-29 13:58:58.583 DEBUG 8272 --- [           main] s.b.w.s.f.OrderedCharacterEncodingFilter : Filter 'characterEncodingFilter' configured for use
2019-06-29 13:58:58.584 DEBUG 8272 --- [           main] o.s.b.w.s.f.OrderedFormContentFilter     : Filter 'formContentFilter' configured for use
2019-06-29 13:58:58.896 DEBUG 8272 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : 5 mappings in 'requestMappingHandlerMapping'
2019-06-29 13:58:58.990  INFO 8272 --- [           main] pertySourcedRequestMappingHandlerMapping : Mapped URL path [/v2/api-docs] onto method [public org.springframework.http.ResponseEntity<springfox.documentation.spring.web.json.Json> springfox.documentation.swagger2.web.Swagger2Controller.getDocumentation(java.lang.String,javax.servlet.http.HttpServletRequest)]
2019-06-29 13:58:59.045 DEBUG 8272 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Patterns [/**/favicon.ico] in 'faviconHandlerMapping'
2019-06-29 13:58:59.128  INFO 8272 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-06-29 13:58:59.146 DEBUG 8272 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
2019-06-29 13:58:59.257 DEBUG 8272 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
2019-06-29 13:58:59.263 DEBUG 8272 --- [           main] .m.m.a.ExceptionHandlerExceptionResolver : ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
2019-06-29 13:58:59.442  INFO 8272 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Context refreshed
2019-06-29 13:58:59.481  INFO 8272 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Found 1 custom documentation plugin(s)
2019-06-29 13:58:59.519  INFO 8272 --- [           main] s.d.s.w.s.ApiListingReferenceScanner     : Scanning for api listing references

Итак, мой вопрос: Почему ComponentScan не обнаруживает мой контроллер REST?

Ответы [ 4 ]

1 голос
/ 04 июля 2019

Создайте свои файлы следующим образом:

Project build.gradle (удалено приложение плагина spring для всех проектов модулей)

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE")
    }
}

subprojects {
    repositories {
        mavenCentral()
    }

    apply plugin: 'java'
    apply plugin: 'idea'
}

module1 build.gradle (применить пружинные плагины и цель bootJar)

dependencies {
    implementation project(':module2')

    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.6.RELEASE'
}

apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
    baseName = 'module1'
    version = '0.0.1-SNAPSHOT'
}

module2 build.gradle (добавлена ​​цель jar)

dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.1.6.RELEASE'
}

jar {
    baseName = 'module2'
    version = '0.0.1-SNAPSHOT'
}

settings.gradle

include 'module1'
include 'module2'

Дело в том, что мы хотим, чтобы второй модуль был построен как обычный сосуд, а основной модуль - как работающий с пружинной загрузкой.С этой настройкой просто gradle build, а затем gradle bootRun из основной папки проекта.

0 голосов
/ 04 июля 2019

В соответствии с соглашением Spring Boot контроллеры должны быть в пакете com.test.controller.

0 голосов
/ 01 июля 2019

Ваше основное приложение Application.java находится в каталоге com.test.application, что означает, что когда по умолчанию приложение springboot запускается, аннотация @SpringBootApplication будет искать bean-компоненты и конфигурации в пакете com.test.application.В документации Springboot указано, что мы должны поместить основное приложение в корневой пакет, чтобы Spring сканировал все под ним.

@ SpringBootApplication - это удобная аннотация, которая добавляет всеиз следующего:

  • @ Configuration помечает класс как источник определений bean-компонентов для контекста приложения.
  • @ EnableAutoConfiguration указывает Spring Boot начинать добавление bean-компонентов на основе настроек пути к классам, другиеbean-компоненты и различные свойства
    settings.
  • Обычно вы добавляете @EnableWebMvc для приложения Spring MVC, но Spring Boot добавляет его автоматически, когда видит spring-webmvc в пути к классам.Это помечает приложение как веб-приложение и
    активирует ключевые поведения, такие как настройка DispatcherServlet.
  • @ ComponentScan говорит Spring искать другие компоненты, конфигурации и службы в пакете hello, позволяя ему
    найдите контроллеры.

Итак, чтобы решить вашу проблему, попробуйте переместить ваше основное приложение в корень вашего пакета com.test или вы можете использовать аннотацию @ComponentScan, чтобы указатькакие пакеты нужно сканировать, например:

@ComponentScan(basePackages = "com.test")
0 голосов
/ 29 июня 2019

Я думаю, что если вы хотите взять свой контроллер из пакета "com.test", используйте опцию basePackages @ComponentScan:

@ComponentScan(basePackages = "com.test")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...