【Spring 系列 給IOC容器添加組件的幾種方式總結】

給Spring 註冊Bean的幾種方式總結。其中使用@Import註解是Spring Boot 完成自動配置的一個核心註解。java

一、Spring 中給IOC容器添加組件的幾種方式

  • 在Spring的配置文件中,配置Bean(基於XML方式)
  • 使用註解(@Controller@Service等)配合上組件掃描器@ComponentScan
  • 使用@Bean註解
  • 使用@Import註解
  • 使用Spring 提供的 FactoryBean

二、對部分方式進行實現

2.一、使用@Bean註解

  • 第一步:定義一個普通類Foo
public class Foo {
}
  • 第二步:定義一個配置類
@Configuration
public class ExampleConfiguration {
    @Bean
    public Foo foo(){
        return new Foo();
    }
}
  • 第三步:測試,遍歷所有的Bean
public class SpringApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExampleConfiguration.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String delegate : beanDefinitionNames){
            System.out.println("Bean Name : "+delegate);
        }
        applicationContext.close();
    }
}
  • 第四步:測試運行結果
Bean Name : org.springframework.context.annotation.internalConfigurationAnnotationProcessor
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@37bba400: startup date [Tue Jul 17 17:36:15 CST 2018]; root of context hierarchy
Bean Name : org.springframework.context.annotation.internalAutowiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalRequiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalCommonAnnotationProcessor
Bean Name : org.springframework.context.event.internalEventListenerProcessor
Bean Name : org.springframework.context.event.internalEventListenerFactory
Bean Name : exampleConfiguration
Bean Name : foo

@Bean註解導入的Bean,默認Bean name爲方法名程序員

2.二、使用@Import註解

2.2.一、@Import(Foo.class)
  • 第一步:修改配置類
@Configuration
@Import(Foo.class)
public class ExampleConfiguration {

}
  • 第二步:測試
public class SpringApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExampleConfiguration.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String delegate : beanDefinitionNames){
            System.out.println("Bean Name : "+delegate);
        }
        applicationContext.close();
    }
}
  • 第三步:測試結果
Bean Name : org.springframework.context.annotation.internalConfigurationAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalAutowiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalRequiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalCommonAnnotationProcessor
Bean Name : org.springframework.context.event.internalEventListenerProcessor
Bean Name : org.springframework.context.event.internalEventListenerFactory
Bean Name : exampleConfiguration
Bean Name : com.hanson.bean.Foo

@Import導入的Bean 默認的Bean Name 爲Bean 的全限定名稱spring

2.2.二、@Import(FooImportSelectorImpl.class)
  • 第一步:定義一個類實現ImportSelector接口,並覆寫其方法selectImports
public class FooImportSelectorImpl implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.hanson.bean.Foo"};
    }
}
  • 第二步:修改配置類
@Configuration
@Import(FooImportSelectorImpl.class)
public class ExampleConfiguration {
}
  • 第三步:啓動測試類,查看運行結果
Bean Name : org.springframework.context.annotation.internalConfigurationAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalAutowiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalRequiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalCommonAnnotationProcessor
Bean Name : org.springframework.context.event.internalEventListenerProcessor
Bean Name : org.springframework.context.event.internalEventListenerFactory
Bean Name : exampleConfiguration
Bean Name : com.hanson.bean.Foo

這個方式有點控制反轉的意思,就是隻須要提供一個類的全限定名稱,就能幫助咱們注入到容器中。shell

2.2.三、@Import(FooImportBeanDefinitionRegistrarImpl.class)
  • 第一步:定義一個類實現ImportBeanDefinitionRegistrar並覆寫其方法registerBeanDefinitions
public class FooImportBeanDefinitionRegistrarImpl implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                        BeanDefinitionRegistry registry) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(Foo.class);
        registry.registerBeanDefinition("fooExample", beanDefinition);
    }
}
  • 第二步:修改配置類
@Configuration
@Import(FooImportBeanDefinitionRegistrarImpl.class)
public class ExampleConfiguration {
}
  • 第三步:運行測試類,並查看結果
Bean Name : org.springframework.context.annotation.internalConfigurationAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalAutowiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalRequiredAnnotationProcessor
Bean Name : org.springframework.context.annotation.internalCommonAnnotationProcessor
Bean Name : org.springframework.context.event.internalEventListenerProcessor
Bean Name : org.springframework.context.event.internalEventListenerFactory
Bean Name : exampleConfiguration
Bean Name : fooExample

這個方式須要程序員手動構建一個BeanDefinition對象。而且爲他設置一個Bean Nameapp

相關文章
相關標籤/搜索