Spring構成部品のスキャン


この文章はインフラの金英漢のスプリング完全征服路線図をもとに整理された.

スイープエレメント


これまで使用していた@Bean自動登録空の対象.実際のプロジェクトでは、空のオブジェクトに登録する必要があるオブジェクトが多いため、これらのオブジェクトが1つ1つ登録されたときに失われるなどの問題が発生する可能性があります.設定ファイルの長さも長くなり、重複作業も深刻になります.この場合,手動登録の代わりに素子スキャンと呼ばれる空の自動登録方法を用いることができる.

@ComponentScan, @Component

@Configuration
@ComponentScan
public class AutoAppConfig {
}
@Component
public class CreateOrderServiceImpl {
}
@Component
public class MemberRepositoryImpl {
}
以上のように設定情報クラスに@ComponentScan説明が追加されていれば、定義@Bean説明の方法がなくても、自動的にスプリング@Component説明クラスの対象が空に登録されます.ではビンの名前は何でしょうか.手動登録では、メソッド名をデフォルト値として使用します.自動登録では、クラス名の前の文字を小文字に変更します.
空の名前空のオブジェクトcreateOrderServiceImplCreateOrderServiceImpl@x01memberRepositoryImplMemberRepositoryImpl@x02@Bean("customName")空の名前を指定できるように、直接指定できる@Component("customName")ロビンの名前.
手動登録が空の場合、以下のように依存関係を注入できます.スキャン素子によって登録された空はどのように依存関係に注入されますか?
public class AppConfig {
    @Bean
    public CreateOrderService createOrderService() {
        return new CreateOrderServiceImpl(memberRepository());
    }
    
    @Bean
    public MemberRepository memberRepository() {
        return new MemberRepositoryImpl();
    }
}
@Autowired自動注入により.自動注入依存関係については,次の記事で議論する.

@ComponentScanの範囲

@ComponentScan説明書を貼ったからといって、項目のすべてのカテゴリをスキャンすることはありません.外部ライブラリにナビゲートする必要があるため、時間がかかります.オプションが指定されていない場合、スキャンはクラスのパッケージとそのサブパッケージのすべてのコンポーネントを定義します.
@Configuration
@ComponentScan(
        basePackages = "hello.service"
)
public class AutoAppConfig {
}
オプションが指定されている場合は、パッケージからすべてのサブパッケージのスキャンを開始します.basePackages = {"hello.repository", "hello.service"}のように、複数の開始位置を配列形式で指定することができる.
構成部品スキャン設定情報はプロジェクトのコア情報であるため、プロジェクトの最上位レベルに配置し、オプションを提供しないことが望ましい.スプリング起動もこの方法を使用します.

Spring Bootプロジェクトでは、プロジェクトの上部にSpringアプリケーションを起動する主なメソッドを含むクラスがあります.このクラスには@SpringBootApplication騒音があり、この騒音には@ComponentScan騒音が含まれています.ちなみにjava宣言は関係を継承していませんがspringは宣言に含まれる宣言を識別する機能をサポートします.

フィルタ-スキャンターゲットから除外


特定の場合、構成部品スキャンから特定のターゲットを除外したい場合があります.このとき使用したのは@ComponentScanの排除フィルターと@Filter騒音です.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyExcludeComponent {
}
@Configuration
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, 
                classes = MyExcludeComponent.class)
)
public class AppConfigWithFilter {
}
type属性ではFilterType.ANNOTATION、class属性ではフィルタとして使用するコメントタイプが用意されています.@MyExcludeComponentアノテーション付きクラスは、構成部品スキャン対象から除外されます.複数の値を指定する場合は、classプロパティを配列形式に書くことができます.FilterTypeANNOTATIONを含む5つのオプションを提供する.
  • ANNOTATION:指定ノイズ(デフォルト)
  • ASSIGNABLE TYPE:指定タイプとサブタイプを指定
  • ASPECTJ:AsspectJモードで指定
  • REGEX:正規表式指定使用
  • CUSTOM:TypeFilterインターフェースによる処理実施
  • スイープエレメント


    次のアノテーションを追加するクラスは、構成部品スキャンのオブジェクトになります.
  • @Component:前述のように、素子スキャン対象として指定されている.
  • @Controller:スプリングMVCモードでコントローラ相当.
  • @Service:スプリングビジネスロジック処理に相当
  • @Repository:スプリングデータアクセス層相当データベース異常をスプリング異常に変換します.
  • @Aspect:スプリングAOP処理に相当します.
  • @Configuration:スプリング設定情報に相当します.文彬をモノトーンで管理する.
  • 構成部品スキャンの競合の処理

  • 空の名前の競合:2つの名前の異なるメンバーRepositoryクラスがコンポーネントスキャンの対象となる可能性があります.この状態でスプリングアプリを起動すると、ConflictingBeanDefinitionException爆発を起こす.この問題は@Componentanotation改名で解決できる.
  • 手動登録でハンビンの名前と衝突
  • @Component
    public class MemberRepository {
        
    }
    @Configuration
    public class AppConfig {
        
        @Bean
        public MemberRepository memberRepository() {
            return new MemberRepository();
        }
    }
    このように、手動で登録した空の名前とスキャン構成部品の空の名前が競合することがあります.この場合、手動で登録したスペースは、構成部品スキャンのスペースを上書きします.つまり、MemberRepositoryタイプの空は容器内に1つしか存在しない.しかし、多くの場合、このような素子スキャンオブジェクトがオーバーライドされるのは、不注意であり、これは、キャプチャが困難なエラーの原因である可能性がある.したがって、SpringBootの最新バージョンでは、手動登録とコンポーネントスキャンの競合時にアプリケーションのロードエラーが発生するようにデフォルト値を変更します.application.propertiesファイルに用意されているspring.main.allow-bean-definition-overriding=trueオプションで、デフォルト値を上書きする動作は許可されますが、推奨される方法ではありません.
    @Configuration
    public class AppConfig {
        
        @Bean
        public MemberRepository memberRepository2() {
            return new MemberRepository();
        }
    }
    以上のように、異なる名前を使用すると、MemberRepositoryタイプの空は競合せずに2つ存在します.この場合、MemberRepositoryタイプのみでは空を区別できないため、適切な空の値を指定する必要があります.@Qualifier自動注入依存関係での処理を宣言する.