@ComponentScan açıklamasını kullanarak birden fazla yol nasıl taranır?


90

Spring 3.1 kullanıyorum ve @Configurationve @ComponentScanözniteliklerini kullanarak bir uygulamayı önyükleme yapıyorum .

Gerçek başlangıç ​​şununla yapılır:

new AnnotationConfigApplicationContext(MyRootConfigurationClass.class);

Bu Yapılandırma sınıfı,

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

ve bu iyi çalışıyor. Ancak taradığım paketler hakkında daha spesifik olmak istiyorum, bu yüzden denedim.

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

Ancak bu, @Componentek açıklama kullanılarak belirtilen bileşenleri bulamadığını söyleyen hatalarla başarısız oluyor .

Peşinde olduğum şeyi yapmanın doğru yolu nedir?

Teşekkürler


Anlayabildiğim kadarıyla aynı anda verilen iki doğru cevap. Daha az puanı olduğu için hage'i kabul edeceğim, ama ikinize de teşekkür ederim.
Programming Guy

Kotlin sürümü için aynı şeyi merak ediyorsanız, bu bir stackoverflow.com/a/62818187/7747942
Sylhare

Yanıtlar:


161

@ComponentScan , aşağıdaki gibi dize dizisi kullanır:

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

Yalnızca bir dizede birden çok paket adı sağladığınızda, Spring bunu tek bir paket adı olarak yorumlar ve bu nedenle bulamaz.


48

Bir temel paket konumunu Dize olarak belirtmenin başka bir tür güvenli alternatifi vardır . API'ye buradan bakın , ancak aşağıda da gösterdim:

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

BasePackageClasses tanımlayıcısını sınıf referanslarınızla birlikte kullanmak, Spring'e bu paketleri taramasını söyleyecektir (aynen bahsedilen alternatifler gibi ), ancak bu yöntem hem tür açısından güvenlidir hem de gelecekteki yeniden düzenleme için IDE desteği ekler - kitabımda büyük bir artı.

API'den okurken Spring, taramak istediğiniz her pakette, bu öznitelik için / tarafından referans olarak kullanılmaktan başka bir amaca hizmet etmeyen bir işlemsiz işaret sınıfı veya arayüz oluşturmanızı önerir.

IMO, işaret sınıflarını sevmiyorum (ama yine de, bunlar tıpkı paket bilgisi sınıflarına çok benziyorlar), ancak tür güvenliği, IDE desteği ve bu taramaya dahil edilmesi gereken temel paketlerin sayısını büyük ölçüde azaltma şüphesiz çok daha iyi bir seçenektir.


Birisi neden @ComponentScan ({"com.app", "com.controllers"}) benim için çalışmıyor ama @ComponentScan (basePackageClasses = {"com.controllers"}) iyi çalışıyor açıklayabilir mi? Her sınıfın adını yazmak sıkıcı buluyorum
xaverras

3
Taramak istediğiniz paket için pakette yalnızca bir sınıf belirtmeniz gerekir. Bu, işaret sınıfı olarak bilinir. Hiyerarşide sınıf içermeyen daha yüksek bir paketi taramanız gerekiyorsa, Spring, bir "yay işaretçisi" arabirimini veya bu pakette yalnızca paket taraması amacıyla tanımlanan son sınıfı kullanan bir teknik önerir.
Prancer

17

Paket adınızı ayrı olarak sağlayın, bir String[]paket adları gerektirir .

Bunun yerine:

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

Bunu kullan:

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

10

Bunu yapmanın bir başka yolu da basePackagesalanı kullanmaktır ; Bu, ComponentScan detaylandırmasının içindeki bir alandır.

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

Jar dosyasından ComponentScan ek açıklaması .class'a bakarsanız, bir Dizeler dizisi alan bir basePackages alanı görürsünüz.

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

Ya da sınıflardan açıkça bahsedebilirsiniz. Sınıf dizisini alan

Class<?>[]  basePackageClasses

4

Birden çok paketi taramak için ComponentScan'i kullanırsınız.

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


1

bu bağımlılığı pom.xml dosyanıza eklediğinizden emin olun

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

Yarım saate yakın harcadıktan sonra teşekkürler, bu eksik bağımlılıktı
DvixExtract

1

@ComponentScans ek açıklamasını da kullanabilirsiniz:

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

4
Lütfen cevabınıza açıklama eklemeyi düşünün
yeya

1

Kullanırım:

@ComponentScan(basePackages = {"com.package1","com.package2","com.package3", "com.packagen"})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.