検索
ホームページJava&#&チュートリアルSpringBoot で @Import アノテーションを使用する方法

    1. @Import による通常クラスの導入

    @Import アノテーションを使用すると、通常のクラスを Bean として定義できます。 @Importは、@SpringBootApplication(スタートアップクラス)、@Configuration(コンフィグレーションクラス)、@Component(コンポーネントクラス)に対応するクラスに追加できます。

    注: @RestController、@Service、@Repository はすべて @Component

    @SpringBootApplication
    @Import(ImportBean.class) // 通过@Import注解把ImportBean添加到IOC容器里面去
    public class MyBatisApplication {
        public static void main(String[] args) {
            SpringApplication.run(MyBatisApplication.class, args);
        }
    }

    に属します。 2. @Import は構成クラス (@) を導入します。構成変更クラス)

    @Import @Importは通常のクラスをBeanとして定義するだけでなく、@Configurationで変更したクラスを導入(構成クラスの導入)することで、構成クラス(配下のすべてのオブジェクト)を有効にすることもできます。構成クラス Bean が IOC コンテナに追加されます)。スターターをカスタマイズするときによく使用されます。

    構成クラスが標準の SpringBoot パッケージ構造 (SpringBootApplication スタートアップ クラス パッケージのルート ディレクトリ) にある場合。 Spring Boot は構成クラスのインポートを自動的に処理するため、 @Import アノテーションを手動で使用する必要はありません。通常、この状況は、@Configuration 構成クラスが標準の Spring Boot パッケージ構造の外側にある場合に当てはまります。そのため、スターターをカスタマイズするときに一般的に使用されます。

    @Configuration(proxyBeanMethods = false)
    @Import({  // import了两个哈
            XXXDataConfiguration.XXXPartOneConfiguration.class,
            XXXDataConfiguration.XXXPartTwoConfiguration.class
    })
    public class XXXDataAutoConfiguration {
    }
    public class XXXDataConfiguration {
        @Configuration(proxyBeanMethods = false)
        static class XXXPartOneConfiguration {
            @Bean
            @ConditionalOnMissingBean
            public BeanForIoc beanForIoc() {
                return new BeanForIoc();
            }
        }
        @Configuration(proxyBeanMethods = false)
        static class XXXPartTwoConfiguration {
    
            /**
             * 省略了@Bean的使用
             */
        }
    }

    3. @Import は、ImportSelector の実装クラスを導入します。

    @Import は、ImportSelector の実装クラスを導入し、selectImports() メソッドによって返されるクラス名を定義することもできます。 ImportSelector インターフェースを Bean として使用します。 selectImports() メソッドの AnnotationMetadata パラメータに注目すると、このパラメータを通じて @Import アノテーションが付けられたクラスに関するさまざまな情報を取得できます。これはパラメータを渡す場合に特に便利です。 SpringBoot の自動設定と @EnableXXX アノテーションは別に存在します。

    public interface ImportSelector {
        /**
         * 用于指定需要注册为bean的Class名称
         * 当在@Configuration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把实现类中返回的Class名称都定义为bean。
         *
         * 通过其参数AnnotationMetadata importingClassMetadata可以获取到@Import标注的Class的各种信息,
         * 包括其Class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为Spring bean的Class名称
         */
        String[] selectImports(AnnotationMetadata importingClassMetadata);
    }

    @Import によって導入された ImportSelector の実装クラスの使用法について、簡単な使用シナリオをいくつか示します (実際の開発は間違いなくこれより複雑です)。

    3.1 静的インポート シナリオ (既知のクラスの挿入)

    静的シナリオ (既知のクラスの挿入)。ImportSelector クラスを実装することで、Bean として定義する必要があるクラスを直接返すのは非常に簡単です。さて、次の例のように。 EnableXXX アノテーションを追加し、XXXConfigurationSelector を通じて既知のクラス XXX を注入しましょう。

    /**
     * XXXConfigurationSelector一定要配合@Import使用
     */
    public class XXXConfigurationSelector implements ImportSelector {
        @Override
        @NonNull
        public String[] selectImports(@NonNull AnnotationMetadata importingClassMetadata) {
            // 把XXX对应的类,定义为Bean
            return new String[]{XXX.class.getName()};
        }
    }
    /**
     * 注意 @Import(XXXConfigurationSelector.class)
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(XXXConfigurationSelector.class)
    public @interface EnableXXX {
    }
    @SpringBootApplication
    @EnableXXX // 使之生效
    public class MyBatisApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MyBatisApplication.class, args);
        }
    
    }

    3.2 動的インポート シナリオ (指定された条件でクラスを挿入する)

    このような関数を作成するには、指定されたパッケージ パスの下にある HelloService インターフェイスを実装するすべてのクラスを Go に Bean として追加する必要があります。 IOCコンテナ内。 @ComponentScan アノテーションは、パスの指定に役立ちます。具体的な実装は次のとおりです。

    public interface HelloService {
        void function();
    
    }
    public class DynamicSelectImport implements ImportSelector {
        /**
         * DynamicSelectImport需要配合@Import()注解使用
         * <p>
         * 通过其参数AnnotationMetadata importingClassMetadata可以获取到@Import标注的Class的各种信息,
         * 包括其Class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为Spring bean的Class名称
         */
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            // 第一步:获取到通过ComponentScan指定的包路径
            String[] basePackages = null;
            // @Import注解对应的类上的ComponentScan注解
            if (importingClassMetadata.hasAnnotation(ComponentScan.class.getName())) {
                Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
                basePackages = (String[]) annotationAttributes.get("basePackages");
            }
            if (basePackages == null || basePackages.length == 0) {
                //ComponentScan的basePackages默认为空数组
                String basePackage = null;
                try {
                    // @Import注解对应的类的包名
                    basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                basePackages = new String[]{basePackage};
            }
            // 第er步,知道指定包路径下所有实现了HelloService接口的类(ClassPathScanningCandidateComponentProvider的使用)
            ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
            TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
            scanner.addIncludeFilter(helloServiceFilter);
            Set<String> classes = new HashSet<>();
            for (String basePackage : basePackages) {
                scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName()));
            }
            // 第三步,返回添加到IOC容器里面去
            return classes.toArray(new String[0]);
        }
    }
    @Configuration
    @ComponentScan("com.tuacy.collect.mybatis") // 指定路径
    @Import(DynamicSelectImport.class)
    public class DynamicSelectConfig {
    }

    4. @Import は、ImportBeanDefinitionRegistrar の実装クラスを導入します。

    @Import は、ImportBeanDefinitionRegistrar の実装クラスを導入します。通常、Bean を動的に登録するために使用されます。最も重要な点は、これらの BeanDefinition に対して 追加の変更や機能拡張を行うこともできるということです。私たちがよく使う mybatis @MapperScan はこの方法で実装されています。

    /**
     * ImportBeanDefinitionRegistrar,我们一般会实现ImportBeanDefinitionRegistrar类,然后配合一个自定义的注解一起使用。而且在注解类上@Import我们的这个实现类。
     * 通过自定义注解的配置,拿到注解的一些元数据。然后在ImportBeanDefinitionRegistrar的实现类里面做相应的逻辑处理,比如把自定义注解标记的类添加到Spring IOC容器里面去。
     */
    public interface ImportBeanDefinitionRegistrar {
    
        /**
         * 根据注解的给定注释元数据,根据需要注册bean定义
         * @param importingClassMetadata 可以拿到@Import的这个class的Annotation Metadata
         * @param registry BeanDefinitionRegistry 就可以拿到目前所有注册的BeanDefinition,然后可以对这些BeanDefinition进行额外的修改或增强。
         */
        void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
    
    }

    @Import によって導入された ImportBeanDefinitionRegistrar の使用については、mybatis の @MapperScan の処理ソース コードを参照することを強くお勧めします。とても興味深い。また、誰もが ImportBeanDefinitionRegistrar の使用法を直感的に理解できるように、非常に簡単な例も示しています。たとえば、指定されたパッケージ パス内の BeanIoc アノテーションを持つすべてのクラスを Bean として登録したいとします。

    具体的な実装は次のとおりです:

    /**
     * 我们会把添加了该注解的类作为bean
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    public @interface BeanIoc {
    
    }
    
    /**
     * 定义包路径。(指定包下所有添加了BeanIoc注解的类作为bean)
     * 注意这里 @Import(BeanIocScannerRegister.class) 的使用
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(BeanIocScannerRegister.class)
    public @interface BeanIocScan {
        String[] basePackages() default "";
    }
    
    
    /**
     * 搜索指定包下所有添加了BeanIoc注解的类,并且把这些类添加到ioc容器里面去
     */
    public class BeanIocScannerRegister implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
    
        private final static String PACKAGE_NAME_KEY = "basePackages";
    
        private ResourceLoader resourceLoader;
    
        @Override
        public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
            //1. 从BeanIocScan注解获取到我们要搜索的包路径
            AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(BeanIocScan.class.getName()));
            if (annoAttrs == null || annoAttrs.isEmpty()) {
                return;
            }
            String[] basePackages = (String[]) annoAttrs.get(PACKAGE_NAME_KEY);
            // 2. 找到指定包路径下所有添加了BeanIoc注解的类,并且把这些类添加到IOC容器里面去
            ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry, false);
            scanner.setResourceLoader(resourceLoader);
            scanner.addIncludeFilter(new AnnotationTypeFilter(BeanIoc.class));
            scanner.scan(basePackages);
        }
    
        @Override
        public void setResourceLoader(ResourceLoader resourceLoader) {
            this.resourceLoader = resourceLoader;
        }
    }
    
    
    /**
     * 使用,使BeanIocScan生效
     */
    @Configuration
    @BeanIocScan(basePackages = "com.tuacy.collect.mybatis")
    public class BeanIocScanConfig {
    }

    以上がSpringBoot で @Import アノテーションを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明
    この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
    Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Apr 25, 2025 am 12:23 AM

    javaispopularforsoss-platformdesktopapplicationsduetoits "writeonce、runaynay" philosophy.1)itusesbytecodatiTatrunnanyjvm-adipplatform.2)ライブラリリケンディンガンドジャヴァフククレアティック - ルルクリス

    Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Apr 25, 2025 am 12:22 AM

    Javaでプラットフォーム固有のコードを作成する理由には、特定のオペレーティングシステム機能へのアクセス、特定のハードウェアとの対話、パフォーマンスの最適化が含まれます。 1)JNAまたはJNIを使​​用して、Windowsレジストリにアクセスします。 2)JNIを介してLinux固有のハードウェアドライバーと対話します。 3)金属を使用して、JNIを介してMacOSのゲームパフォーマンスを最適化します。それにもかかわらず、プラットフォーム固有のコードを書くことは、コードの移植性に影響を与え、複雑さを高め、パフォーマンスのオーバーヘッドとセキュリティのリスクをもたらす可能性があります。

    プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?Apr 25, 2025 am 12:12 AM

    Javaは、クラウドネイティブアプリケーション、マルチプラットフォームの展開、および言語間の相互運用性を通じて、プラットフォームの独立性をさらに強化します。 1)クラウドネイティブアプリケーションは、GraalvmとQuarkusを使用してスタートアップ速度を向上させます。 2)Javaは、埋め込みデバイス、モバイルデバイス、量子コンピューターに拡張されます。 3)Graalvmを通じて、JavaはPythonやJavaScriptなどの言語とシームレスに統合して、言語間の相互運用性を高めます。

    Javaの強力なタイピングは、プラットフォームの独立性にどのように貢献しますか?Javaの強力なタイピングは、プラットフォームの独立性にどのように貢献しますか?Apr 25, 2025 am 12:11 AM

    Javaの強力なタイプ化されたシステムは、タイプの安全性、統一タイプの変換、多型を通じてプラットフォームの独立性を保証します。 1)タイプの安全性は、コンパイル時間でタイプチェックを実行して、ランタイムエラーを回避します。 2)統一された型変換ルールは、すべてのプラットフォームで一貫しています。 3)多型とインターフェイスメカニズムにより、コードはさまざまなプラットフォームで一貫して動作します。

    Javaネイティブインターフェイス(JNI)がプラットフォームの独立性をどのように妥協できるかを説明します。Javaネイティブインターフェイス(JNI)がプラットフォームの独立性をどのように妥協できるかを説明します。Apr 25, 2025 am 12:07 AM

    JNIはJavaのプラットフォームの独立を破壊します。 1)JNIは特定のプラットフォームにローカルライブラリを必要とします。2)ローカルコードをターゲットプラットフォームにコンパイルおよびリンクする必要があります。3)異なるバージョンのオペレーティングシステムまたはJVMは、異なるローカルライブラリバージョンを必要とする場合があります。

    Javaのプラットフォームの独立性を脅かしたり強化したりする新しいテクノロジーはありますか?Javaのプラットフォームの独立性を脅かしたり強化したりする新しいテクノロジーはありますか?Apr 24, 2025 am 12:11 AM

    新しいテクノロジーは、両方の脅威をもたらし、Javaのプラットフォームの独立性を高めます。 1)Dockerなどのクラウドコンピューティングとコンテナ化テクノロジーは、Javaのプラットフォームの独立性を強化しますが、さまざまなクラウド環境に適応するために最適化する必要があります。 2)WebAssemblyは、Graalvmを介してJavaコードをコンパイルし、プラットフォームの独立性を拡張しますが、パフォーマンスのために他の言語と競合する必要があります。

    JVMのさまざまな実装は何ですか、そしてそれらはすべて同じレベルのプラットフォームの独立性を提供しますか?JVMのさまざまな実装は何ですか、そしてそれらはすべて同じレベルのプラットフォームの独立性を提供しますか?Apr 24, 2025 am 12:10 AM

    JVMの実装が異なると、プラットフォームの独立性が得られますが、パフォーマンスはわずかに異なります。 1。OracleHotspotとOpenJDKJVMは、プラットフォームの独立性で同様に機能しますが、OpenJDKは追加の構成が必要になる場合があります。 2。IBMJ9JVMは、特定のオペレーティングシステムで最適化を実行します。 3. Graalvmは複数の言語をサポートし、追加の構成が必要です。 4。AzulzingJVMには、特定のプラットフォーム調整が必要です。

    プラットフォームの独立性は、開発コストと時間をどのように削減しますか?プラットフォームの独立性は、開発コストと時間をどのように削減しますか?Apr 24, 2025 am 12:08 AM

    プラットフォームの独立性により、開発コストが削減され、複数のオペレーティングシステムで同じコードセットを実行することで開発時間を短縮します。具体的には、次のように表示されます。1。開発時間を短縮すると、1セットのコードのみが必要です。 2。メンテナンスコストを削減し、テストプロセスを統合します。 3.展開プロセスを簡素化するための迅速な反復とチームコラボレーション。

    See all articles

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    Video Face Swap

    Video Face Swap

    完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

    ホットツール

    SecLists

    SecLists

    SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

    mPDF

    mPDF

    mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

    SublimeText3 Linux 新バージョン

    SublimeText3 Linux 新バージョン

    SublimeText3 Linux 最新バージョン

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    DVWA

    DVWA

    Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、