文档章节

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

HansonReal
 HansonReal
发布于 2018/07/17 17:53
字数 701
阅读 77
收藏 2

给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

© 著作权归作者所有

HansonReal

HansonReal

粉丝 21
博文 15
码字总数 11891
作品 0
无锡
程序员
私信 提问
【Spring Boot 系列 自动配置原理分析】

在Spring Boot 中我们想要使用某个功能只需要在POM文件中添加对应的依赖。然后整个应用程序便具备了这个功能。那么这是如何实现的呢? 通过分析Spring Boot 示例程序来分析Spring Boot 自动配...

HansonReal
2018/07/18
56
1
三条路线告诉你如何掌握Spring IoC容器的核心原理

一、前言 前三篇已经从历史的角度和大家一起探讨了为什么会有Spring,Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国。本节的主要目的就是通过一个切入点带大家一...

Java小铺
2018/08/27
0
0
Spring IoC(更新中)

概念 IoC(控制反转,也叫依赖注入DI)是Spring的核心,几乎Spring的所有组件都要建立在此基础之上,包括AOP,声明式事务,SpringMVC等等。那么IoC的主要目的是什么呢?两个字“解耦”。为什么...

互联网小龙虾
2014/03/04
148
0
【死磕 Spring】----- IOC 之深入理解 Spring IoC

版权声明:版权声明:转载前请留言获得作者许可,转载后标明作者 chenssy 和原文出处。原创不易,感谢您的支持 https://blog.csdn.net/chenssy/article/details/82343456 在一开始学习 Spri...

chenssy
2018/09/03
0
0
【死磕 Spring】—– IOC 之深入理解 Spring IoC

在一开始学习 Spring 的时候,我们就接触 IoC 了,作为 Spring 第一个最核心的概念,我们在解读它源码之前一定需要对其有深入的认识,本篇为【死磕 Spring】系列博客的第一篇博文,主要介绍 ...

chenssy
2018/09/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

哪些情况下适合使用云服务器?

我们一直在说云服务器价格适中,具备弹性扩展机制,适合部署中小规模的网站或应用。那么云服务器到底适用于哪些情况呢?如果您需要经常原始计算能力,那么使用独立服务器就能满足需求,因为他...

云漫网络Ruan
今天
10
0
Java 中的 String 有没有长度限制

转载: https://juejin.im/post/5d53653f5188257315539f9a String是Java中很重要的一个数据类型,除了基本数据类型以外,String是被使用的最广泛的了,但是,关于String,其实还是有很多东西...

低至一折起
今天
22
0
OpenStack 简介和几种安装方式总结

OpenStack :是一个由NASA和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。项目目标是提供实施简单、可大规模扩展、丰富、标准统一的云计算管理平台。OpenSta...

小海bug
昨天
11
0
DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
昨天
9
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部