インターフェイスおよび関連する注記は、のクラスSpring5ソースコード解析を開始します

しかし、知識の概要をいくつかの基本的なコア:

必要が@Configurationを追加する際の春ブートプロジェクトが開始し、@ComponentScan

サードパーティのjarパッケージ@Bean @Configuration +は容器に注ぎました。OKの@ComponentSscanと同様@Controller内部ダイレクト@Service

@Scope実施形態では、単一達成することができます

飢えた男を作成するための呼び出しのデフォルトの開始時刻は、作成するときに呼び出している(ただし、時間、プロジェクトの開始時間を消費する)、他のです 

コンポーネントを制御する必要がある構成要素を除く利用@ComponentScan排除、

上記プラス@ComponentScan Configクラスおよび他の注釈の注入を制御します

 

 

 

 

マルチ利用条件レジスタ・ビーン@Conditionオブジェクト、環境に応じてjuez決定

サードパーティ製の@import急速注入は、Beanオブジェクト

オープンのSpringBoot Emablexxx原則

ベースのImportBeanDefinitionRegister登録豆

登録BeanオブジェクトベースのFactoryBeanの

 

 

 

Springの拡張インターフェイス:条件


 

ビーン後の制御のために、一定の条件がコンテナに登録することを許可することができます満たしています。

ちょうどそれのようなシステムエンティティを記述します。

パブリック クラスOS {
     プライベート文字列名;
    プライベート整数バージョン。

    パブリックOS(){ 
    } 

    @Override 
    パブリック文字列のtoString(){
         リターン "ハロー********************* OS {" + 
                "NAME = '" +名+ '\'」+ 
                "バージョン=" +バージョン+ 
                '}' 
    } 
}

プロファイル(等価XML)

@Configuration
 パブリック クラスのMyConfig { 

    @Bean 
    @Conditional(MyCondition。クラスパブリックOSのOS(){ 
        System.out.printlnは( "ttttttttttttttttttttt" )。
        返す 新しいOSを(); 
    } 
}

制御された条件:

パブリック クラス MyCondition 実装条件条件の{
     / ** 
     * 
     * @param conditionContext現在のコンテキストを取得する
     * @paramの詳細annotatedTypeMetadata現在の注釈を取得
     * @return 
     * / 
    パブリック ブールマッチ(ConditionContext conditionContext、AnnotatedTypeMetadata annotatedTypeMetadata){ 
        環境環境は = conditionContext.getEnvironment( ); 
        文字列OSNAME = environment.getProperty( "os.name" );
         IF(osName.equals( "Windowsは7" )){
             リターン falseに; 
        } 
        場合(osName.equals( "Windowsの10" )){
             戻り 
        } 
        を返す 
    } 
}

テストカテゴリ:

パブリック クラスのテスト{
     公共 静的 ボイドメイン(文字列[]引数){ 
        AnnotationConfigApplicationContextのApplicationContext = 新しい AnnotationConfigApplicationContext(のMyConfig。クラス)。
        文字列[] beanDefinitionNames = applicationContext.getBeanDefinitionNames()。
        (文字列名:beanDefinitionNames){ 
            System.out.printlnは(名前)。
        } 
        OS osTest =(OS)applicationContext.getBean( "OS" )。
        System.out.println(osTest)。
    } 
}

結果:

 

 2. @importコメント


なぜそれ@import考えるために注釈を使うのか? 

 注意事項@Beanそれは何のシナリオですか?サインジャーを外にロードされました。30豆がある場合は、一つ一つがああ書くのは非常に面倒です

したがって、簡略化操作@import、外側パッケージがジャースプリングIOC容器に注入されます。@Beanに相当。Beanオブジェクトの登録@import、IDは、現在のクラスの完全なパスです。

Configurationクラス:

@Configuration 
@import(OS。クラスパブリック クラスのMyConfig { 
}

試験方法:

パブリック クラスのテスト{
     公共 静的 ボイドメイン(文字列[]引数){ 
        AnnotationConfigApplicationContextのApplicationContext = 新しい AnnotationConfigApplicationContext(のMyConfig。クラス)。
        文字列[] beanDefinitionNames = applicationContext.getBeanDefinitionNames()。
        (文字列名:beanDefinitionNames){ 
            System.out.printlnは(名前)。
        } 
        // インポート的特殊性 
        OS osTest =(OS)applicationContext.getBean( "com.toov5.config.beanTest.OS" )。
        System.out.println(osTest)。
    } 
}

 

 @importと@Bean違い:

 @Bean注册的bean的id是方法名称

 @Import当前类完整地址

共同应用场景都是引用外部jar包。

 

3. @EnableXXX


 

开启某某功能。底层使用@Import注解实现的

底层调用的就是@Import注解

场景: 封装一个框架,把不支持springboot的,鼓捣成支持springboot的!

实体类:

public class PayEntity {
}

注解:

/**
 * 启动时候加入该注解,开启功能,会将实体类注入到容器中
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({PayEntity.class})
public @interface EnablePayEntity {

}

启动:

@Configuration
@EnablePayEntity
public class MyConfig {
}

 

测试:

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames){
            System.out.println(name);
        }
    }
}

结果:

 

补充下: 可以@Import多个 ”,“解决。

 

4. ImportSelector接口 (跟 @Import注解一样的,只不过这个是原生api罢了)


 

  实体类1:

public class MemberEntity {
}

实体类2:

public class PersonEntity {
}

原生接口的实现:

public class MyImportSeletcor implements ImportSelector {
    /**
     * 注解信息
     * @param annotationMetadata
     * @return
     */
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"com.toov5.config.beanTest.MemberEntity", "com.toov5.config.beanTest.PersonEntity"};
    }
}

启动类:

@Configuration
@Import(MyImportSeletcor.class)
public class MyConfig {
}

测试类:

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames){
            System.out.println(name);
        }
    }
}

结果:

 

 

5. ImportBeanDefinitionRegister接口  手动往ioc 注入bean


 

 Spring容器中 Bean的信息,都是由BeanDefinition描述的

可以看下:

各种方法,Bean的各种信息。

实体类:

public class PersonEntity {
}

接口实现,手动注入实体类

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * 注解信息
     * @param annotationMetadata
     * @param beanDefinitionRegistry
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //手动注册到ioc容器中
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(PersonEntity.class);
        //IOC源码里面肯定有这个的!!! 对象放到IOC容器中就叫注册 (底层是个map 线程安全的)
        beanDefinitionRegistry.registerBeanDefinition("personEntity", rootBeanDefinition);
    }
}

启动类:

@Configuration
@Import(MyImportBeanDefinitionRegistrar.class)
public class MyConfig {

}

测试类:

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames){
            System.out.println(name);
        }
    }
}

运行结果:

 

6. 基于FactoryBean


 FactoryBean也可以用来注册Bean

 

启动方式千万万,随便使用:

实体类:

public class PersonEntity {
}

FactoryBean:

public class MyFactoryBean implements FactoryBean<PersonEntity> {
    @Override
    public PersonEntity getObject() throws Exception {
        return new PersonEntity();
    }

    @Override
    public Class<?> getObjectType() {
        return PersonEntity.class;
    }

    @Override
    public boolean isSingleton() {
        //默认情况下是true。单例
        return true;
    }
    //往ioc容器中注入对象

}

启动类:

@Configuration
public class MyConfig {

    @Bean
    public MyFactoryBean myFactoryBean(){
        return new MyFactoryBean();
    }
}

测试类:

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        PersonEntity personEntity1 = (PersonEntity)applicationContext.getBean("myFactoryBean");
        PersonEntity personEntity2 = (PersonEntity)applicationContext.getBean("myFactoryBean");
        System.out.println(personEntity1 == personEntity2);
    }
}

 

 


 

自己写“抄”个注解玩玩

 

自定义一个注解:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface toov5 {
}

实体类:

@toov5
public class Hello {
}

启动采用扫包的方式:扫包的范围

@Configuration
@ComponentScan("com.toov5.config.beanTest.entity")
public class MyConfig {

}

测试:

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames){
            System.out.println(name);
        }
    }
}

测试结果:

 

 小结: spring 注入bean到容器方式:

 @Bean  @Import ,一般用于外部的jar包

 其他的 @Service @Repository 注入对象底层其实都一样,就是区分不同的场景。使用的时候需要@ComponentScan注解扫包

 还有就是实现一系列相应的接口去实现注入Bean 的方式

 

おすすめ

転載: www.cnblogs.com/toov5/p/11223350.html