Интеграция ComponentScan с явными базовыми пакетами, необходимыми для весенней загрузки?

#spring-boot #annotations #spring-integration #spring-annotations #component-scan

Вопрос:

У меня есть приложение Spring Boot (с использованием Spring Boot 2.4.11), в котором я использую интеграцию Spring. Я добавил org.springframework.boot:spring-boot-starter-integration и, следовательно, ожидал @IntegrationComponentScan , что буду активен по умолчанию. Действительно, я нахожу выпуск 2037, который, по-видимому, предполагает это. Кроме того, я вижу эту аннотацию на org.springframework.boot.autoconfigure.integration.IntegrationAutoConfigurationScanRegistrar.IntegrationComponentScanConfiguration .

Однако мои @MessagingGateway аннотированные интерфейсы не были использованы Весной. Я попытался добавить явное @IntegrationComponentScan в один из моих @Configuration классов, но это тоже не сработало.

Это начало работать, как только я также указал явное basePackages значение для этой аннотации, так что:

 @Configuration
@IntegrationComponentScan(basePackages = "com.example.app.integration")
public class MyConfigurationClass {
}
 

и, конечно, мои аннотированные интерфейсы находятся в пакете ниже com.example.app.integration .

Я что-то упускаю? Я не смог найти никаких ссылок на @IntegrationComponentScan документацию по весенней загрузке. Другие подобные аннотации (например @EnableJpaRepositories , для данных Spring или @EntityScan ) не являются строго необходимыми, если только вам не нужно настроить область сканирования.

Я также нашел проблему 3375, которая , по-видимому, предполагает, что я должен посмотреть @AutoConfigurationPackage , но:

  • Я не могу найти никакого упоминания об этой аннотации в документации по весенней загрузке
  • Я подозреваю, что это будет применимо к ЛЮБОЙ другой аннотации «сканирование», включенной Spring Boot, поэтому мой basePackages в этом случае, вероятно, должен указывать на какой-то пакет, очень близкий к «корню» моего приложения
  • почему эта аннотация не требуется для других @*Scan аннотаций, подобных приведенным выше?

Ответ №1:

Я думаю, вам нужно показать структуру вашего проекта. Это работает так, как ожидалось:

  1. У меня есть такой интерфейс, как com.example.integration.gateway.MyGateway
  2. Мой основной класс находится в разделе com.example.integration.IntegrationApplication с таким содержанием, как:
     @SpringBootApplication
    public class IntegrationApplication {
     

Это все еще работает, даже если у меня есть это MyGateway в com.example.integration упаковке.

Заключить. @SpringBootApplication Он помечен тем @ComponentScan , где Spring начинает сканирование компонентов из пакета, в котором это @SpringBootApplication объявлено, и вплоть до его подпакетов.

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

 /**
 * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
 * for a type-safe alternative to String-based package names.
 * <p>
 * <strong>Note:</strong> this setting is an alias for
 * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity}
 * scanning or Spring Data {@link Repository} scanning. For those you should add
 * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and
 * {@code @Enable...Repositories} annotations.
 * @return base packages to scan
 * @since 1.3.0
 */
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
 

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