Używam Spring 3.1 i ładuję aplikację przy użyciu atrybutów @Configuration
i @ComponentScan
.
Właściwy start jest zakończony
new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);
Ta klasa konfiguracji jest opatrzona adnotacją
@Configuration
@ComponentScan("com.my.package")
public class MyRootConfigurationClass
i to działa dobrze. Chciałbym jednak bardziej szczegółowo opisać pakiety, które skanuję, więc spróbowałem.
@Configuration
@ComponentScan("com.my.package.first,com.my.package.second")
public class MyRootConfigurationClass
Jednak kończy się to niepowodzeniem z błędami informującymi mnie, że nie może znaleźć komponentów określonych za pomocą @Component
adnotacji.
Jaki jest właściwy sposób robienia tego, czego szukam?
Dzięki
java
spring
annotations
Programista
źródło
źródło
Odpowiedzi:
@ComponentScan używa tablicy ciągów, takiej jak ta:
@ComponentScan({"com.my.package.first","com.my.package.second"})
Jeśli podasz wiele nazw pakietów w jednym ciągu, Spring interpretuje to jako jedną nazwę pakietu i dlatego nie może go znaleźć.
źródło
Istnieje inna bezpieczna dla typu alternatywa dla określania lokalizacji pakietu podstawowego jako String. Zobacz API tutaj , ale zilustrowałem również poniżej:
@ComponentScan(basePackageClasses = {ExampleController.class, ExampleModel.class, ExmapleView.class})
Użycie specyfikatora basePackageClasses z odwołaniami do klas powie Springowi, aby przeskanował te pakiety (tak jak wspomniane alternatywy ), ale ta metoda jest zarówno bezpieczna dla typów, jak i dodaje obsługę IDE dla przyszłych refaktoryzacji - ogromny plus w mojej książce.
Czytając z interfejsu API, Spring sugeruje utworzenie klasy lub interfejsu znacznika no-op w każdym pakiecie, który chcesz skanować, który służy wyłącznie do wykorzystania jako odniesienie dla / przez ten atrybut.
IMO, nie lubię klas znaczników (ale z drugiej strony są one prawie takie same jak klasy informacji o pakiecie), ale bezpieczeństwo typów, obsługa IDE i drastyczne zmniejszenie liczby pakietów podstawowych potrzebnych do tego skanowania jest bez wątpienia znacznie lepszą opcją.
źródło
Podaj nazwę pakietu osobno, wymaga to
String[]
dla nazw pakietów.Zamiast tego:
@ComponentScan("com.my.package.first,com.my.package.second")
Użyj tego:
@ComponentScan({"com.my.package.first","com.my.package.second"})
źródło
Innym sposobem na to jest użycie
basePackages
pola; czyli pole wewnątrz adnotacji ComponentScan.@ComponentScan(basePackages={"com.firstpackage","com.secondpackage"})
Jeśli spojrzysz na adnotację ComponentScan .class z pliku jar, zobaczysz pole basePackages, które przyjmuje tablicę ciągów znaków
public @interface ComponentScan { String[] basePackages() default {}; }
Możesz też wyraźnie wspomnieć o klasach. Który przyjmuje szereg klas
źródło
ComponentScan służy do skanowania wielu pakietów za pomocą
@ComponentScan({"com.my.package.first","com.my.package.second"})
źródło
upewnij się, że dodałeś tę zależność w swoim pom.xml
źródło
Używam:
@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})
źródło
Możesz również użyć adnotacji @ComponentScans:
@ComponentScans(value = { @ComponentScan("com.my.package.first"), @ComponentScan("com.my.package.second") })
źródło