【Spring 系列 给IOC容器添加组件的几种方式总结】

给Spring 注册Bean的几种方式总结。其中使用@Import注解是Spring Boot 完成自动配置的一个核心注解。

1、Spring 中给IOC容器添加组件的几种方式

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

2、对部分方式进行实现

2.1、使用@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.2、使用@Import注解
2.2.1、@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 的全限定名称

2.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

这个方式有点控制反转的意思,就是只需要提供一个类的全限定名称,就能帮助我们注入到容器中。

2.2.3、@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 Name

转载于:https://my.oschina.net/serve/blog/1858348

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值