Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² Π² этой Π³Π»Π°Π²Π΅ для указания ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ BeanDefinition Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ Spring, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ XML. Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… Ρ‡Π΅Ρ€Π΅Π· Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ источника. Однако Π΄Π°ΠΆΠ΅ Π² этих ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… опрСдСлСния "Π±Π°Π·ΠΎΠ²Ρ‹Ρ…" Π±ΠΈΠ½ΠΎΠ² явно ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² XML-Ρ„Π°ΠΉΠ»Π΅, Π° Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ зависимостСй. Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ описываСтся Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ нСявного обнаруТСния ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ² ΠΏΡƒΡ‚Π΅ΠΌ сканирования classpath. ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Ρ‹ – это классы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ критСриям Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π° ΠΈ ΠΈΠΌΠ΅ΡŽΡ‚ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π°, зарСгистрированноС Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅. Π­Ρ‚ΠΎ устраняСт Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ использования XML для выполнСния рСгистрации Π±ΠΈΠ½Π°. ВмСсто этого Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, @Component), выраТСния Ρ‚ΠΈΠΏΠΎΠ² AspectJ ΠΈΠ»ΠΈ собствСнныС кастомныС ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΠΈ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ классы ΠΈΠΌΠ΅ΡŽΡ‚ опрСдСлСния Π±ΠΈΠ½Π°, зарСгистрированныС Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅.

Начиная со Spring 3.0, ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, прСдоставляСмыС ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠΌ Spring JavaConfig, ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ основной ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Spring Framework. Π­Ρ‚ΠΎ позволяСт Π²Π°ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Π±ΠΈΠ½Ρ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Java, Π° Π½Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½Ρ‹Ρ… XML-Ρ„Π°ΠΉΠ»ΠΎΠ². ВзглянитС Π½Π° Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @Configuration, @Bean, @Import ΠΈ @DependsOn ΠΊΠ°ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ использования этих Π½ΠΎΠ²Ρ‹Ρ… возмоТностСй.

@Component ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ стСрСотипныС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ

Аннотация @Repository – это ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ для любого класса, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ исполняСт Ρ€ΠΎΠ»ΡŒ ΠΈΠ»ΠΈ стСрСотип рСпозитория (Ρ‚Π°ΠΊΠΆΠ΅ извСстного ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ доступа ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ ΠΈΠ»ΠΈ DAO). Π‘Ρ€Π΅Π΄ΠΈ способов использования этого ΠΌΠ°Ρ€ΠΊΠ΅Ρ€Π° - автоматичСскоС ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ.

Spring прСдоставляСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ стСрСотипныС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ: @Component, @Service ΠΈ @Controller. @Component – это ΠΎΠ±Ρ‰ΠΈΠΉ стСрСотип для любого ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°, управляСмого Spring. @Repository, @Service ΠΈ @Controller – это спСциализированныС Ρ„ΠΎΡ€ΠΌΡ‹ @Component для Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… случаСв использования (Π½Π° уровнях хранСния, сСрвисном ΠΈ прСдставлСния, соотвСтствСнно). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ свои ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π½Ρ‹Π΅ классы с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ @Component, Π½ΠΎ, Ссли вмСсто этого Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… @Repository, @Service ΠΈΠ»ΠΈ @Controller, ваши классы Π±ΡƒΠ΄ΡƒΡ‚ большС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ инструмСнтами ΠΈΠ»ΠΈ связи с аспСктами. НапримСр, эти стСрСотипныС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ цСлями для срСзов. @Repository, @Service ΠΈ @Controller Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡƒΡ‚ нСсти Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ сСмантику Π² Π±ΡƒΠ΄ΡƒΡ‰ΠΈΡ… выпусках Spring Framework. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ссли Π²Ρ‹ Π΄Π΅Π»Π°Π΅Ρ‚Π΅ Π²Ρ‹Π±ΠΎΡ€ ΠΌΠ΅ΠΆΠ΄Ρƒ @Component ΠΈ @Service для вашСго сСрвисного уровня, @Service Π±ΡƒΠ΄Π΅Ρ‚ явно Π»ΡƒΡ‡ΡˆΠΈΠΌ Π²Ρ‹Π±ΠΎΡ€ΠΎΠΌ. Аналогично, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½ΠΎ Ρ€Π°Π½Π΅Π΅, @Repository ΡƒΠΆΠ΅ поддСрТиваСтся ΠΊΠ°ΠΊ ΠΌΠ°Ρ€ΠΊΠ΅Ρ€ для автоматичСского прСобразования ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Π½Π° вашСм ΡƒΡ€ΠΎΠ²Π½Π΅ хранСния.

ИспользованиС ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ ΠΈ составных Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ

МногиС ΠΈΠ· Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ, прСдоставляСмых Spring, ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ Π² качСствС ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ Π² вашСм собствСнном ΠΊΠΎΠ΄Π΅. ΠœΠ΅Ρ‚Π°-аннотация – это аннотация, которая ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½Π° ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ. НапримСр, аннотация @Service, упомянутая Ρ€Π°Π½Π΅Π΅, ΠΌΠ΅Ρ‚Π°-аннотируСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ @Component, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

Java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    // ...
}
  1. Аннотация @Component Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ аннотация @Service обрабатываСтся Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ @Component.
Kotlin
@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
annotation class Service {
    // ...
}
  1. Аннотация @Component Π΄Π΅Π»Π°Π΅Ρ‚ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎ аннотация @Service обрабатываСтся Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ @Component.

Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ для создания "составных Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ". НапримСр, аннотация @RestController ΠΈΠ· Spring MVC состоит ΠΈΠ· @Controller ΠΈ @ResponseBody.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, составныС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎ нСобходимости ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΈΠ· ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ для обСспСчСния возмоТности настройки. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ особСнно ΠΏΠΎΠ»Π΅Π·Π½ΠΎ, Ссли Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ. НапримСр, аннотация @SessionScope Π² Spring ТСстко ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅Ρ‚ имя области доступности ΠΊΠ°ΠΊ session, Π½ΠΎ ΠΏΡ€ΠΈ этом позволяСт Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ proxyMode. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ листингС ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ SessionScope:

Java
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_SESSION)
public @interface SessionScope {
    /**
     * ПсСвдоним для {@link Scope#proxyMode}.
     * <p>По ΡƒΠΌΠΎΠ»Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ {@link ScopedProxyMode#TARGET_CLASS}.
     */
    @AliasFor(annotation = Scope.class)
    ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
Kotlin
@Target(AnnotationTarget.TYPE, AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Scope(WebApplicationContext.SCOPE_SESSION)
annotation class SessionScope(
        @get:AliasFor(annotation = Scope::class)
        val proxyMode: ScopedProxyMode = ScopedProxyMode.TARGET_CLASS
)

Π—Π°Ρ‚Π΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ @SessionScope Π±Π΅Π· объявлСния proxyMode ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

Java
@Service
@SessionScope
public class SessionScopedService {
    // ...
}
Kotlin
@Service
@SessionScope
class SessionScopedService {
    // ...
}

Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ для proxyMode, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

Java
@Service
@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
public class SessionScopedUserService implements UserService {
    // ...
}
Kotlin
@Service
@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
class SessionScopedUserService : UserService {
    // ...
}

Π‘ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° Π²ΠΈΠΊΠΈ-страницС Spring Annotation Programming Model.

АвтоматичСскоС ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ классов ΠΈ рСгистрация ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ Π±ΠΈΠ½ΠΎΠ²

Spring ΠΌΠΎΠΆΠ΅Ρ‚ автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Ρ‚ΡŒ стСрСотипизированныС классы ΠΈ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ экзСмпляры BeanDefinition Π² ApplicationContext. НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Π΄Π²Π° класса ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Ρ‹:

Java
@Service
public class SimpleMovieLister {
    private MovieFinder movieFinder;
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}
Kotlin
@Service
class SimpleMovieLister(private val movieFinder: MovieFinder)
Java
@Repository
public class JpaMovieFinder implements MovieFinder {
    // рСализация ΠΎΠΏΡƒΡ‰Π΅Π½Π° для ясности
}
Kotlin
@Repository
class JpaMovieFinder : MovieFinder {
    // рСализация ΠΎΠΏΡƒΡ‰Π΅Π½Π° для ясности
}

Для автоматичСского обнаруТСния этих классов ΠΈ рСгистрации ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Π±ΠΈΠ½ΠΎΠ² Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ @ComponentScan Π² класс @Configuration, Π³Π΄Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ basePackages являСтся ΠΎΠ±Ρ‰ΠΈΠΌ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠΌ для Π΄Π²ΡƒΡ… классов. (Как Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ список, Ρ€Π°Π·Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ запятыми, Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ с запятой ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ класса).

Java
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
    // ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"])
class AppConfig  {
    // ...
}
Для краткости Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ value Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ @ComponentScan("org.example")).

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="org.example"/>
</beans>
ИспользованиС <context:component-scan> нСявно Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ <context:annotation-config>. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π½Π΅Ρ‚ нСобходимости Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ элСмСнт <context:annotation-config> ΠΏΡ€ΠΈ использовании <context:component-scan>.

Π‘ΠΊΠ°Π½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² classpath Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ наличия ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… записСй ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° Π² classpath. Если Π²Ρ‹ собираСтС JAR с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ant, ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π½Π΅ Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚Π΅Π»ΡŒ "Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ„Π°ΠΉΠ»Ρ‹" Π² Π·Π°Π΄Π°Ρ‡Π΅ JAR. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ ΠΏΡƒΡ‚ΠΈ классов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ Π½Π° основании ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊ бСзопасности Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… срСдах – Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π°Π²Ρ‚ΠΎΠ½ΠΎΠΌΠ½Ρ‹Π΅ прилоТСния Π½Π° JDK 1.7.0_45 ΠΈ Π²Ρ‹ΡˆΠ΅ (Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ установки довСряСмой Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ('Trusted-Library') Π² Π²Π°ΡˆΠΈΡ… манифСстах - см. https://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).

По ΠΏΡƒΡ‚ΠΈ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ JDK 9 (Jigsaw) сканированиС classpath Spring Π² Ρ†Π΅Π»ΠΎΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ оТидаСтся. Однако ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ классы Π²Π°ΡˆΠΈΡ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² экспортированы Π² дСскрипторы module-info. Если Π²Ρ‹ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ Spring Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π΅ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‡Π»Π΅Π½Ρ‹ Π²Π°ΡˆΠΈΡ… классов, ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ 'ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹' (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ объявлСниС opens вмСсто объявлСния exports Π² вашСм дСскрипторС module-info).

Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, AutowiredAnnotationBeanPostProcessor ΠΈ CommonAnnotationBeanPostProcessor нСявно Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‚ΡΡ ΠΏΡ€ΠΈ использовании элСмСнта component-scan. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π΄Π²Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΈ ΡΠΎΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ΡΡ вмСстС - ΠΈ всС это Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΈΠ½Π°, ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹Ρ… Π½Π° XML.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ AutowiredAnnotationBeanPostProcessor ΠΈ CommonAnnotationBeanPostProcessor, Π²ΠΊΠ»ΡŽΡ‡ΠΈΠ² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ annotation-config со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ false.

ИспользованиС Ρ„ΠΈΠ»ΡŒΡ‚Ρ€ΠΎΠ² для настройки сканирования

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ классы, Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ @Component, @Repository, @Service, @Controller, @Configuration ΠΈΠ»ΠΈ кастомной Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ, которая сама Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π° @Component, ΡΠ²Π»ΡΡŽΡ‚ΡΡ СдинствСнными ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Π°ΠΌΠΈ для обнаруТСния. Однако Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΈ Ρ€Π°ΡΡˆΠΈΡ€ΡΡ‚ΡŒ эту Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π±ΠΎΡ‚Ρ‹, примСняя кастомныС Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΠΈΡ… ΠΊΠ°ΠΊ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ includeFilters ΠΈΠ»ΠΈ excludeFilters Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @ComponentScan (ΠΈΠ»ΠΈ ΠΊΠ°ΠΊ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ элСмСнты <context:include-filter /> ΠΈΠ»ΠΈ <context:exclude-filter /> элСмСнта <context:component-scan> Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ XML). ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π° Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ наличия Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² type ΠΈ expression. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Ρ‚Π°Π±Π»ΠΈΡ†Π΅ описаны ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°Ρ†ΠΈΠΈ:

Table 5. Filter Types
Π’ΠΈΠΏ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π° ΠŸΡ€ΠΈΠΌΠ΅Ρ€ выраТСния ОписаниС

annotation (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ)

org.example.SomeAnnotation

Аннотация, которая Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ present ΠΈΠ»ΠΈ meta-present Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Ρ‚ΠΈΠΏΠ° Π² Ρ†Π΅Π»Π΅Π²Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ….

assignable

org.example.SomeClass

Класс (ΠΈΠ»ΠΈ интСрфСйс), Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹ (Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Ρ‹ ΠΈΠ»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹) Ρ†Π΅Π»Π΅Π²Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹.

aspectj

org.example..*Service+

Π’Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° AspectJ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Ρ†Π΅Π»Π΅Π²Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹.

regex

org\.example\.Default.*

РСгулярноС Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ для сопоставлСния с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ классов Ρ†Π΅Π»Π΅Π²Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

custom

org.example.MyTypeFilter

ΠšΠ°ΡΡ‚ΠΎΠΌΠ½Π°Ρ рСализация интСрфСйса org.springframework.core.type.TypeFilter.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° конфигурация, ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ всС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @Repository ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ вмСсто Π½ΠΈΡ… Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ с "Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ-Π·Π°Π³Π»ΡƒΡˆΠΊΠΎΠΉ":

Java
@Configuration
@ComponentScan(basePackages = "org.example",
        includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
        excludeFilters = @Filter(Repository.class))
public class AppConfig {
    // ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"],
        includeFilters = [Filter(type = FilterType.REGEX, pattern = [".*Stub.*Repository"])],
        excludeFilters = [Filter(Repository::class)])
class AppConfig {
    // ...
}

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ листингС ΠΏΠΎΠΊΠ°Π·Π°Π½ эквивалСнт Π½Π° XML:

<beans>
    <context:component-scan base-package="org.example">
        <context:include-filter type="regex"
                expression=".*Stub.*Repository"/>
        <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>
Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Ρ‹ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π·Π°Π΄Π°Π² useDefaultFilters=false Π² Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΈΠ»ΠΈ прСдоставив use-default-filters="false" Π² качСствС Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° элСмСнта <component-scan/>. Π’Π°ΠΊΠΈΠΌ способом ΠΌΠΎΠΆΠ½ΠΎ эффСктивно ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ автоматичСскоС ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ классов, Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… @Component, @Repository, @Service, @Controller, @RestController ΠΈΠ»ΠΈ @Configuration.

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΈΠ½ΠΎΠ² Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°Ρ…

ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ Spring ΠΌΠΎΠ³ΡƒΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ Π²Π½ΠΎΡΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ опрСдСлСния Π±ΠΈΠ½ΠΎΠ² Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€. Π­Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ‚ΠΎΠΉ ΠΆΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @Bean, которая ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для опрСдСлСния ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΈΠ½Π° Π² классах, ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹Ρ… Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ @Configuration. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ:

Java
@Component
public class FactoryMethodComponent {
    @Bean
    @Qualifier("public")
    public TestBean publicInstance() {
        return new TestBean("publicInstance");
    }
    public void doWork() {
        // РСализация ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΎΠΏΡƒΡ‰Π΅Π½Π°
    }
}
Kotlin
@Component
class FactoryMethodComponent {
    @Bean
    @Qualifier("public")
    fun publicInstance() = TestBean("publicInstance")
    fun doWork() {
        // РСализация ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΎΠΏΡƒΡ‰Π΅Π½Π°
    }
}

ΠŸΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ класс являСтся ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ Spring, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ спСцифичный для прилоТСния ΠΊΠΎΠ΄ Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ doWork(). Однако ΠΎΠ½ Ρ‚Π°ΠΊΠΆΠ΅ вносит ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄, ΡΡΡ‹Π»Π°ΡŽΡ‰ΠΈΠΉΡΡ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ publicInstance(). Аннотация @Bean ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ свойства опрСдСлСния Π±ΠΈΠ½Π°, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Ρ‡Π΅Ρ€Π΅Π· Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ @Qualifier. Π”Ρ€ΡƒΠ³ΠΈΠ΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ уровня ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π΄Π°Π½Ρ‹, это @Scope, @Lazy ΠΈ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ кастомных ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ².

Π’ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊ Ρ€ΠΎΠ»ΠΈ Π² ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ @Lazy Π½Π° Ρ‚ΠΎΡ‡ΠΊΠΈ внСдрСния, ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹Π΅ @Autowired ΠΈΠ»ΠΈ @Inject. Π’ Π΄Π°Π½Π½ΠΎΠΌ контСкстС это ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π²Π½Π΅Π΄Ρ€Π΅Π½ΠΈΡŽ прокси с ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ. Однако Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ с задСйствованиСм прокси довольно ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½. ВмСсто Π½Π΅Π³ΠΎ для слоТных ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… взаимодСйствий, Π² частности, Π² сочСтании с Π½Π΅ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ зависимостями, ΠΌΡ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ObjectProvider<MyTargetBean>.

ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΈ связанныС поля ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΎ упомянуто Ρ€Π°Π½Π΅Π΅, с Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ автоматичСского обнаруТСния ΠΈ связывания ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² @Bean. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ:

Java
@Component
public class FactoryMethodComponent {
    private static int i;
    @Bean
    @Qualifier("public")
    public TestBean publicInstance() {
        return new TestBean("publicInstance");
    }
    // использованиС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° ΠΈ автоматичСского обнаруТСния ΠΈ связывания ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
    @Bean
    protected TestBean protectedInstance(
            @Qualifier("public") TestBean spouse,
            @Value("#{privateInstance.age}") String country) {
        TestBean tb = new TestBean("protectedInstance", 1);
        tb.setSpouse(spouse);
        tb.setCountry(country);
        return tb;
    }
    @Bean
    private TestBean privateInstance() {
        return new TestBean("privateInstance", i++);
    }
    @Bean
    @RequestScope
    public TestBean requestScopedInstance() {
        return new TestBean("requestScopedInstance", 3);
    }
}
Kotlin
@Component
class FactoryMethodComponent {
    companion object {
        private var i: Int = 0
    }
    @Bean
    @Qualifier("public")
    fun publicInstance() = TestBean("publicInstance")
    // использованиС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° ΠΈ автоматичСского обнаруТСния ΠΈ связывания ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π°
    @Bean
    protected fun protectedInstance(
            @Qualifier("public") spouse: TestBean,
            @Value("#{privateInstance.age}") country: String) = TestBean("protectedInstance", 1).apply {
        this.spouse = spouse
        this.country = country
    }
    @Bean
    private fun privateInstance() = TestBean("privateInstance", i++)
    @Bean
    @RequestScope
    fun requestScopedInstance() = TestBean("requestScopedInstance", 3)
}

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ выполняСтся автоматичСскоС ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ΠΈ связываниС String ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° country со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ свойства age Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Π±ΠΈΠ½Π° с ΠΈΠΌΠ΅Π½Π΅ΠΌ privateInstance. Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ языка Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Spring Expression Language опрСдСляСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ свойства Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ #{ <expression> }. Для Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ @Value Ρ€Π°ΡΠΏΠΎΠ·Π½Π°Π²Π°Ρ‚Π΅Π»ΡŒ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ настроСн Π½Π° поиск ΠΈΠΌΠ΅Π½ Π±ΠΈΠ½ΠΎΠ² ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ тСкста выраТСния.

Начиная с вСрсии Spring Framework 4.3, Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Ρ‚ΠΈΠΏΠ° InjectionPoint (ΠΈΠ»ΠΈ Π΅Π³ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ подкласса: DependencyDescriptor) для получСния доступа ΠΊ Ρ‚ΠΎΡ‡ΠΊΠ΅ внСдрСния запроса, которая Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ созданиС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Π±ΠΈΠ½Π°. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ это касаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ фактичСского создания экзСмпляров Π±ΠΈΠ½Π°, Π° Π½Π΅ внСдрСния ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… экзСмпляров. Как слСдствиС, эта функция ΠΈΠΌΠ΅Π΅Ρ‚ смысл для Π±ΠΈΠ½ΠΎΠ², находящихся Π² области доступности prototype. Для Π΄Ρ€ΡƒΠ³ΠΈΡ… областСй доступности Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ распознаСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎΡ‡ΠΊΡƒ внСдрСния, которая Π²Ρ‹Π·Π²Π°Π»Π° созданиС Π½ΠΎΠ²ΠΎΠ³ΠΎ экзСмпляра Π±ΠΈΠ½Π° Π² Π΄Π°Π½Π½ΠΎΠΉ области доступности (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ, которая Π²Ρ‹Π·Π²Π°Π»Π° созданиС Π±ΠΈΠ½Π°-ΠΎΠ΄ΠΈΠ½ΠΎΡ‡ΠΊΠΈ с ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ). Π’ Ρ‚Π°ΠΊΠΈΡ… сцСнариях ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ прСдоставлСнныС ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚ΠΎΡ‡ΠΊΠΈ внСдрСния с соблюдСниСм сСмантичСской остороТности. Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ InjectionPoint:

Java
@Component
public class FactoryMethodComponent {
    @Bean @Scope("prototype")
    public TestBean prototypeInstance(InjectionPoint injectionPoint) {
        return new TestBean("prototypeInstance for " + injectionPoint.getMember());
    }
}
Kotlin
@Component
class FactoryMethodComponent {
    @Bean
    @Scope("prototype")
    fun prototypeInstance(injectionPoint: InjectionPoint) =
            TestBean("prototypeInstance for ${injectionPoint.member}")
}

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ с Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ @Bean Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ Spring ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΈΠ½Π°Ρ‡Π΅, Ρ‡Π΅ΠΌ ΠΈΡ… Π°Π½Π°Π»ΠΎΠ³ΠΈ Π² классС с Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ@Configuration Π² Spring. Π Π°Π·Π½ΠΈΡ†Π° состоит Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ классы @Component нСльзя Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ CGLIB для ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Π° Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈ ΠΏΠΎΠ»Π΅ΠΉ. CGLIB-проксированиС – это срСдство, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² ΠΈΠ»ΠΈ ΠΏΠΎΠ»Π΅ΠΉ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ², ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Π½Ρ‹Ρ… Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ @Bean, Π² классах с Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ @Configuration создаСт ссылки ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… Π±ΠΈΠ½Π° Π½Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹. Π’Π°ΠΊΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ с использованиСм Ρ‚ΠΈΠΏΠΎΠ²ΠΎΠΉ сСмантики Java, Π° проходят Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Ρ‹Ρ‡Π½ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ ΠΈ проксированиС Π±ΠΈΠ½ΠΎΠ² Π² Spring, Π΄Π°ΠΆΠ΅ ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ ΠΊ Π΄Ρ€ΡƒΠ³ΠΈΠΌ Π±ΠΈΠ½Π°ΠΌ Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹Π΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² @Bean. Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ этого, Π²Ρ‹Π·ΠΎΠ² ΠΌΠ΅Ρ‚ΠΎΠ΄Π° ΠΈΠ»ΠΈ поля Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅ @Bean Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ классС @Component ΠΈΠΌΠ΅Π΅Ρ‚ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ сСмантику Java, Π±Π΅Π· ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ CGLIB ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹, Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ @Bean, ΠΊΠ°ΠΊ статичСскиС, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΈΡ… Π±Π΅Π· создания содСрТащСго ΠΈΡ… ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ класса Π² качСствС экзСмпляра. Π­Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ особый смысл ΠΏΡ€ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ Π±ΠΈΠ½ΠΎΠ² постпроцСссора (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚ΠΈΠΏΠ° BeanFactoryPostProcessor ΠΈΠ»ΠΈ BeanPostProcessor), ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‚Π°ΠΊΠΈΠ΅ Π±ΠΈΠ½Ρ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π° Ρ€Π°Π½Π½Π΅ΠΉ стадии ΠΆΠΈΠ·Π½Π΅Π½Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ запуска Π΄Ρ€ΡƒΠ³ΠΈΡ… частСй ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π² этот ΠΌΠΎΠΌΠ΅Π½Ρ‚.

Π’Ρ‹Π·ΠΎΠ²Ρ‹ статичСских ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² @Bean Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΏΠ΅Ρ€Π΅Ρ…Π²Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠΌ, Π΄Π°ΠΆΠ΅ Π²Π½ΡƒΡ‚Ρ€ΠΈ классов @Configuration (ΠΊΠ°ΠΊ описано Ρ€Π°Π½Π΅Π΅ Π² этом Ρ€Π°Π·Π΄Π΅Π»Π΅), ΠΈΠ·-Π·Π° тСхничСских ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ: ΠŸΠΎΠ΄ΠΊΠ»Π°ΡΡΡ‹ CGLIB ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нСстатичСскиС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹. Как слСдствиС, прямой Π²Ρ‹Π·ΠΎΠ² Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° @Bean ΠΈΠΌΠ΅Π΅Ρ‚ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ сСмантику Java, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ‡Π΅Π³ΠΎ нСзависимый экзСмпляр возвращаСтся прямо ΠΈΠ· Ρ„Π°Π±Ρ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°.

Π’ΠΈΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² @Bean Π½Π° языкС Java Π½Π΅ ΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ нСпосрСдствСнного влияния Π½Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Π±ΠΈΠ½Π° Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅ Spring. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ свободно ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ свои Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΠΎ своСму ΡƒΡΠΌΠΎΡ‚Ρ€Π΅Π½ΠΈΡŽ Π² классах, Π½Π΅ относящихся ΠΊ @Configuration, Π° Ρ‚Π°ΠΊΠΆΠ΅ для статичСских ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Π² любом мСстС. Однако ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ @Bean Π² классах @Configuration Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ пСрСопрСдСляСмыми, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ, ΠΎΠ½ΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ ΠΊΠ°ΠΊ private ΠΈΠ»ΠΈ final.

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ @Bean Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ для Π±Π°Π·ΠΎΠ²Ρ‹Ρ… классов Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΈΠ»ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ класса, Π° Ρ‚Π°ΠΊΠΆΠ΅ для ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² Π½Π° Java 8 ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹Ρ… Π² интСрфСйсах, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΡ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠΌ ΠΈΠ»ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΌ классом. Π­Ρ‚ΠΎ позволяСт ΠΎΡ‡Π΅Π½ΡŒ Π³ΠΈΠ±ΠΊΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΊ созданию слоТных ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΉ, ΠΏΡ€ΠΈ этом Π΄Π°ΠΆΠ΅ мноТСствСнноС наслСдованиС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΈΡ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Java 8 ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, начиная с вСрсии Spring 4.2.

НаконСц, ΠΎΠ΄ΠΈΠ½ класс ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ нСсколько ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² @Bean для ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Π±ΠΈΠ½Π° Π² качСствС ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² для использования Π² зависимости ΠΎΡ‚ доступных зависимостСй Π²ΠΎ врСмя выполнСния. Π­Ρ‚ΠΎ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ, Ρ‡Ρ‚ΠΎ ΠΈ ΠΏΡ€ΠΈ Π²Ρ‹Π±ΠΎΡ€Π΅ самого "ΠΆΠ°Π΄Π½ΠΎΠ³ΠΎ" конструктора ΠΈΠ»ΠΈ Ρ„Π°Π±Ρ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… сцСнариях ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ: Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ с наибольшим количСством ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΡ… зависимостСй выбираСтся Π²ΠΎ врСмя построСния, Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ Ρ‚ΠΎΠΌΡƒ, ΠΊΠ°ΠΊ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ ΠΌΠ΅ΠΆΠ΄Ρƒ нСсколькими @Autowired конструкторами.

ИмСнованиС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² с автоматичСским ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ΠΌ

Если ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ автоматичСски обнаруТиваСтся Π² процСссС сканирования, Π΅Π³ΠΎ имя Π±ΠΈΠ½Π° гСнСрируСтся стратСгиСй BeanNameGenerator, извСстной Π΄Π°Π½Π½ΠΎΠΌΡƒ сканСру. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, любая стСрСотипная аннотация Spring(@Component, @Repository, @Service ΠΈ @Controller), содСрТащая value ΠΈΠΌΠ΅Π½ΠΈ, Ρ‚Π΅ΠΌ самым прСдоставляСт это имя ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΡŽ Π±ΠΈΠ½Π°.

Если такая аннотация Π½Π΅ содСрТит value ΠΈΠΌΠ΅Π½ΠΈ ΠΈΠ»ΠΈ для любого Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ кастомными Ρ„ΠΈΠ»ΡŒΡ‚Ρ€Π°ΠΌΠΈ), Π³Π΅Π½Π΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΈΠΌΠ΅Π½ Π±ΠΈΠ½ΠΎΠ² ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅ΠΏΠΎΠ»Π½ΠΎΠ΅ имя класса Π±Π΅Π· Π·Π°Π³Π»Π°Π²Π½Ρ‹Ρ… Π±ΡƒΠΊΠ². НапримСр, Ссли Π±Ρ‹Π»ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ классы ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Ρ‚ΠΎ ΠΈΡ… ΠΈΠΌΠ΅Π½Π° Π±ΡƒΠ΄ΡƒΡ‚ myMovieLister ΠΈ movieFinderImpl:

Java
@Service("myMovieLister")
public class SimpleMovieLister {
    // ...
}
Kotlin
@Service("myMovieLister")
class SimpleMovieLister {
    // ...
}
Java
@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}
Kotlin
@Repository
class MovieFinderImpl : MovieFinder {
    // ...
}

Если Π²Ρ‹ Π½Π΅ ΠΆΠ΅Π»Π°Π΅Ρ‚Π΅ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° ΡΡ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΡŽ имСнования Π±ΠΈΠ½ΠΎΠ² ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ ΡΡ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΡŽ имСнования. Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ интСрфСйс BeanNameGenerator ΠΈ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ Π² Π½Π΅Π³ΠΎ конструктор ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π—Π°Ρ‚Π΅ΠΌ ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ ΠΏΠΎΠ»Π½ΠΎΠ΅ имя класса ΠΏΡ€ΠΈ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ сканСра, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΈ опрСдСлСния Π±ΠΈΠ½Π°.

Если Π²Ρ‹ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ с ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Π°ΠΌΠΈ ΠΈΠΌΠ΅Π½ ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ нСсколько автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² ΠΈΠΌΠ΅ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Π΅ Π½Π΅ΠΏΠΎΠ»Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π° классов (Ρ‚.Π΅. классы с ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΌΠΈ ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ, Π½ΠΎ находящиСся Π² Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚Π°Ρ…), Π²Π°ΠΌ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡ‚ΡŒΡΡ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ BeanNameGenerator, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΏΠΎΠ»Π½ΠΎΠ΅ имя класса для Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Π±ΠΈΠ½Π°. Начиная со Spring Framework 5.2.3, для Ρ‚Π°ΠΊΠΈΡ… Ρ†Π΅Π»Π΅ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ FullyQualifiedAnnotationBeanNameGenerator, находящийся Π² ΠΏΠ°ΠΊΠ΅Ρ‚Π΅ org.springframework.context.annotation.
Java
@Configuration
@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
public class AppConfig {
    // ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"], nameGenerator = MyNameGenerator::class)
class AppConfig {
    // ...
}
<beans>
    <context:component-scan base-package="org.example"
        name-generator="org.example.MyNameGenerator" />
</beans>

Как ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, слСдуСт ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ имя вмСстС с Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠ΅ΠΉ Π²ΠΎ всСх случаях, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ явно ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Π½Π΅Π³ΠΎ. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, автоматичСски Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Π΅ ΠΈΠΌΠ΅Π½Π° подходят для Ρ‚Π΅Ρ… случаСв, ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° связываниС.

ΠŸΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»Π΅Π½ΠΈΠ΅ области доступности для автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²

Как ΠΈ Π² Ρ†Π΅Π»ΠΎΠΌ Π² случаС с ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ, управляСмыми Spring, стандартной ΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ распространСнной ΠΎΠ±Π»Π°ΡΡ‚ΡŒΡŽ доступности для автоматичСски ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² являСтся singleton. Однако ΠΈΠ½ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ иная ΠΎΠ±Π»Π°ΡΡ‚ΡŒ доступности, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @Scope. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ имя области доступности Π² Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

Java
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}
Kotlin
@Scope("prototype")
@Repository
class MovieFinderImpl : MovieFinder {
    // ...
}
Π‘Π°ΠΌΠΎΠ°Π½Π°Π»ΠΈΠ· Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ @Scope осущСствляСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ класса Π±ΠΈΠ½Π° (для Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²) ΠΈΠ»ΠΈ для Ρ„Π°Π±Ρ€ΠΈΡ‡Π½ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° (для ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² @Bean). Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ Π±ΠΈΠ½ΠΎΠ² Π½Π° XML, здСсь Π½Π΅Ρ‚ понятия наслСдования ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΉ Π±ΠΈΠ½ΠΎΠ², Π° ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ наслСдования Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ классов Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ значСния для Ρ†Π΅Π»Π΅ΠΉ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ….

Для получСния ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Π²Π΅Π±-спСцифичСских областях доступности, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ "request" ΠΈΠ»ΠΈ "session" Π² контСкстС Spring, см. Ρ€Π°Π·Π΄Π΅Π» "ΠžΠ±Π»Π°ΡΡ‚ΠΈ доступности Request, Session, Application ΠΈ WebSocket". Как ΠΈ Π² случаС с Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΌΠΈ аннотациями для этих областСй доступности, Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ свои собствСнныС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ Spring: Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΡŽ, ΠΌΠ΅Ρ‚Π°-Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ @Scope("prototype") ΠΈ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±ΡŠΡΠ²Π»ΡΡŽΡ‰ΡƒΡŽ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ с прокси, входящим Π² ΠΎΠ±Π»Π°ΡΡ‚ΡŒ доступности (scoped-proxy mode).

Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΊΠ°ΡΡ‚ΠΎΠΌΠ½ΡƒΡŽ ΡΡ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΡŽ для Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ области доступности, Π° Π½Π΅ ΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π½Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, основанный Π½Π° Π°Π½Π½ΠΎΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ интСрфСйс ScopeMetadataResolver. ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅ конструктор ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π—Π°Ρ‚Π΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ ΡƒΡ‚ΠΎΡ‡Π½Π΅Π½Π½ΠΎΠ΅ имя класса ΠΏΡ€ΠΈ настройкС сканСра, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ ΠΈ опрСдСлСния Π±ΠΈΠ½Π°:
Java
@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
    // ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"], scopeResolver = MyScopeResolver::class)
class AppConfig {
    // ...
}
<beans>
    <context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver"/>
</beans>

ΠŸΡ€ΠΈ использовании Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ Π½Π΅ΠΎΠ΄ΠΈΠ½ΠΎΡ‡Π½Ρ‹Ρ… областСй видимости ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ созданиС прокси для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² области видимости. Для этого для элСмСнта component-scan имССтся Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ scoped-proxy. Π’Ρ€ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Ρ… значСния: no, interfaces ΠΈ targetClass. НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ конфигурация ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡŽ стандартных динамичСских прокси ΠΈΠ· JDK:

Java
@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
    // ...
}
Kotlin
@Configuration
@ComponentScan(basePackages = ["org.example"], scopedProxy = ScopedProxyMode.INTERFACES)
class AppConfig {
    // ...
}
<beans>
    <context:component-scan base-package="org.example" scoped-proxy="interfaces"/>
</beans>

Π£ΠΊΠ·Π°Π½ΠΈΠ΅ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π² Π΄Π°Π½Π½ΠΎΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ использованиС Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ @Qualifier ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² для обСспСчСния Ρ‚ΠΎΠ½ΠΊΠΎΠ³ΠΎ контроля ΠΏΡ€ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ² Π½Π° автоматичСскоС ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ΠΈ связываниС. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ эти ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Π±Ρ‹Π»ΠΈ основаны Π½Π° опрСдСлСниях Π±ΠΈΠ½ΠΎΠ² Π½Π° XML, ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Π±Ρ‹Π»ΠΈ ΡƒΠΊΠ°Π·Π°Π½Ρ‹ Π² опрСдСлСниях Π±ΠΈΠ½ΠΎΠ²-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ² с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ qualifier ΠΈΠ»ΠΈ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… элСмСнтов meta элСмСнта bean Π½Π° XML. Если Π²Ρ‹ ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ‚Π΅ΡΡŒ Π½Π° сканированиС classpath для автоматичСского обнаруТСния ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° с аннотациями Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Ρ‚ΠΈΠΏΠΎΠ² для класса-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Π°. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ‚Ρ€ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ этот ΠΏΡ€ΠΈΡ‘ΠΌ:

Java
@Component
@Qualifier("Action")
public class ActionMovieCatalog implements MovieCatalog {
    // ...
}
Kotlin
@Component
@Qualifier("Action")
class ActionMovieCatalog : MovieCatalog
Java
@Component
@Genre("Action")
public class ActionMovieCatalog implements MovieCatalog {
    // ...
}
Kotlin
@Component
@Genre("Action")
class ActionMovieCatalog : MovieCatalog {
    // ...
}
Java
@Component
@Offline
public class CachingMovieCatalog implements MovieCatalog {
    // ...
}
Kotlin
@Component
@Offline
class CachingMovieCatalog : MovieCatalog {
    // ...
}
Как ΠΈ Π² случаС с Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎΠΌ Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹Ρ… способов, основанных Π½Π° аннотациях, слСдуСт ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ привязаны ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΡŽ самого класса, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ использованиС XML позволяСт нСскольким Π±ΠΈΠ½Π°ΠΌ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΊΠ²Π°Π»ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ эти ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ экзСмпляра, Π° Π½Π΅ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ класса.

ГСнСрация индСкса ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ²

Π₯отя сканированиС ΠΏΡƒΡ‚Π΅ΠΉ класса происходит ΠΊΡ€Π°ΠΉΠ½Π΅ быстро, ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ запуска Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, создав статичСский список ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ² Π²ΠΎ врСмя компиляции. Π’ этом Ρ€Π΅ΠΆΠΈΠΌΠ΅ всС ΠΌΠΎΠ΄ΡƒΠ»ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ сканирования ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ², Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π·Π°Π΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ этот ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ.

Π’Π°ΡˆΠΈ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ²Ρ‹ @ComponentScan ΠΈΠ»ΠΈ <context:component-scan/> Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΡΡ‚Π°Π²Π°Ρ‚ΡŒΡΡ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Ρ‚ΡŒ контСкст Π½Π° сканированиС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ² Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… ΠΏΠ°ΠΊΠ΅Ρ‚Π°Ρ…. Если ApplicationContext ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ индСкс, ΠΎΠ½ автоматичСски ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ, Π° Π½Π΅ сканируСт classpath.

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ индСкс, Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ, содСрТащСму ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ цСлями для Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΈΠ² сканирования ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ². Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ это ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Maven:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-indexer</artifactId>
        <version>5.3.24</version>
        <optional>true</optional>
    </dependency>
</dependencies>

Π’ Gradle 4.5 ΠΈ Π±ΠΎΠ»Π΅Π΅ Ρ€Π°Π½Π½ΠΈΡ… вСрсиях Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ compileOnly, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

dependencies {
    compileOnly "org.springframework:spring-context-indexer:5.3.24"
}

Π’ Gradle 4.6 ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ·Π΄Π½ΠΈΡ… вСрсиях Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ Π½ΡƒΠΆΠ½ΠΎ ΠΎΠ±ΡŠΡΠ²Π»ΡΡ‚ΡŒ Π² ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ annotationProcessor, ΠΊΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

dependencies {
    annotationProcessor "org.springframework:spring-context-indexer:5.3.24"
}

АртСфакт spring-context-indexer Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„Π°ΠΉΠ» META-INF/spring.components, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² jar-Ρ„Π°ΠΉΠ».

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с этим Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ Π² вашСй IDE, spring-context-indexer Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ зарСгистрирован ΠΊΠ°ΠΊ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π°Π½Π½ΠΎΡ‚Π°Ρ†ΠΈΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ индСкс Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒΡΡ ΠΏΡ€ΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ²-ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚ΠΎΠ².
ИндСкс активируСтся автоматичСски, ΠΊΠΎΠ³Π΄Π° Ρ„Π°ΠΉΠ» META-INF/spring.components Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΉΠ΄Π΅Π½ Π² ΠΏΡƒΡ‚ΠΈ классов. Если индСкс частично доступСн для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ (ΠΈΠ»ΠΈ сцСнариСв использования), Π½ΠΎ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ создан для всСго прилоТСния, ΠΌΠΎΠΆΠ½ΠΎ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌΡƒ Ρ‚ΠΈΠΏΡƒ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡƒΡ‚ΠΈ классов (ΠΊΠ°ΠΊ Ссли Π±Ρ‹ индСкс Π²ΠΎΠΎΠ±Ρ‰Π΅ отсутствовал), установив spring.index.ignore Π² true, Π»ΠΈΠ±ΠΎ ΠΊΠ°ΠΊ систСмноС свойство JVM, Π»ΠΈΠ±ΠΎ Ρ‡Π΅Ρ€Π΅Π· ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ SpringProperties.