Як сканувати кілька шляхів за допомогою анотації @ComponentScan?


89

Я використовую Spring 3.1 і завантажую програму за допомогою атрибутів @Configurationand @ComponentScan.

Фактичний старт зроблено з

new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);

Цей клас конфігурації коментується

@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass

і це чудово працює. Однак я хотів би бути більш конкретним щодо пакунків, які сканую, тому спробував.

@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass

Однак це не вдається, оскільки помилки говорять мені, що він не може знайти компоненти, зазначені за допомогою @Componentанотації.

Який правильний спосіб робити те, що я шукаю?

Дякую


Дві правильні відповіді, дані приблизно одночасно, наскільки я можу сказати. Я дам згоду hage лише тому, що він має менше очок, але дякую вам обом.
Хлопець із програмування

Якщо вам цікаво , то ж саме для Котлин версії перевірити це один stackoverflow.com/a/62818187/7747942
Sylhare

Відповіді:


159

@ComponentScan використовує масив рядків, наприклад:

@ComponentScan({"com.my.package.first","com.my.package.second"})

Коли ви надаєте кілька імен пакунків лише в одному рядку, Spring інтерпретує це як одне ім'я пакета, і тому не може його знайти.


48

Існує ще одна безпечна для типу альтернатива вказівці розташування базового пакета як рядка. Дивіться API тут , але я також проілюстрував це нижче:

@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})

Використання специфікатора basePackageClasses з посиланнями на ваш клас допоможе Spring просканувати ці пакунки (як і згадані альтернативи ), але цей метод одночасно безпечний для типу та додає підтримку IDE для майбутнього рефакторингу - величезний плюс у моїй книзі.

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

IMO, мені не подобаються маркери-класи (але знову ж таки, вони майже подібні до класів info-package), але безпека типу, підтримка IDE та різке зменшення кількості базових пакетів, необхідних для цього сканування є, без сумніву, набагато кращим варіантом.


Хтось може пояснити, чому @ComponentScan ({"com.app", "com.controllers"}) у мене не працює, але @ComponentScan (basePackageClasses = {"com.controllers"}) працює добре? Мені нудно писати кожне ім’я класу
xaverras

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

17

Вкажіть назву пакета окремо, для цього потрібно вказати String[]назву пакета.

Замість цього:

@ComponentScan("com.my.package.first,com.my.package.second")

Використовуй це:

@ComponentScan({"com.my.package.first","com.my.package.second"})

10

Інший спосіб зробити це - використання basePackagesполя; яке є полем всередині анотації ComponentScan.

@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})

Якщо ви заглянете до анотації ComponentScan .class із файлу jar, ви побачите поле basePackages, яке бере масив рядків

public @interface ComponentScan {
String[] basePackages() default {};
}

Або ви можете прямо згадати класи. Що приймає масив класів

Class<?>[]  basePackageClasses

4

Ви використовуєте ComponentScan для сканування декількох пакунків за допомогою

@ComponentScan({"com.my.package.first","com.my.package.second"})


1

переконайтесь, що ви додали цю залежність у свій pom.xml

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

Спасибі, витративши близько півгодини, це була відсутність залежності
DvixExtract

1

Я використовую:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})

0

Ви також можете використовувати анотацію @ComponentScans:

@ComponentScans(value = { @ComponentScan("com.my.package.first"),
                          @ComponentScan("com.my.package.second") })

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