注册Bean到IOC容器大致分为4种:

①、包扫描+组件注解(@Controller、@Service、@Repository、@Component)

针对类是我们自己编写的情况

②、@Bean注解

针对导入第三方包里面的类的情况

③、@Import

针对快速导入某一个类的情况,如仅仅只是调用无参构造创建对象。

1)@Import注解直接导入

2)ImportSelector手动导入Bean到容器中

3)ImportBeanDefinitionRegistrar手动注册bean到容器中

④、FactoryBean(Bean工厂)

  1. 默认获取到的是工厂bean调用getObject方法创建的对象

  2. 要获取工厂bean本身,我们需要给id前面加一个&(&FactoryBean)

实战过Spring的人来说,前两种方式可谓是最常见不过了。而后两种方式在开发中比较少见,因此本文主要介绍@ImportFactoryBean这两种方式。

@Import方式

@Import注解源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}

通过源码我们可以发现,@Import注解只能放置在类上,并且有一个value属性,是一个Class类型的数组,我们将需要导入到IOC容器的Bean的字节码放置这个数组中,spring容器就会通过反射创建对象到ioc容器中。

--测试

--配置类

@Configuration
@Import({Color.class, Red.class})
public class SpringConfig {
}

--单元测试

@Test
public void testApplicationContext2() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}

--测试结果

ImportSelector方式

ImportSelect是一个接口,接口中有一个抽象方法selectImports,返回值为一个String数组,

spring会自动将返回的String数组中的类创建对象到ioc容器中去。

--MyImportSelector代码

public class MyImportSelector implements ImportSelector {
// 返回值就是导入到容器中的组件的全类名
// AnnotationMetadata:封装了当前标注@Import注解的类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[]{"org.cjw.pojo.Blue", "org.cjw.pojo.Yellow"};
}
}

--配置类

@Configuration
@Import({Color.class, Red.class, MyImportSelector.class})
public class SpringConfig {
}

--单元测试

同上

--测试结果

ImportBeanDefinitionRegistrar

这种方式和ImportSelector方式很类似,都是实现一个接口,然后在重写的方法中编写bean的导入规则。

--MyImportBeanDefinitionRegistrar代码

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
// 编写注册判断规则
// 指定Bean的类型,作用域等等
RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);
// 注册一个bean到ioc容器中,并指定beanName
beanDefinitionRegistry.registerBeanDefinition("rainBow", beanDefinition);
}
}

--配置类

@Configuration
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class SpringConfig {

--单元测试

同上

--测试结果

FactoryBean

FactoryBean是一个接口,我们需要编写一个类实现它,并重写getObjectgetObejctTypeisSingleton方法。

  • getObject:IOC容器会执行此方法得到Bean,并放到IOC容器中去。

  • getObjectType:获取Bean的类型。

  • isSingleton:设置Bean是否为单例,返回值为true为单例,false为多例,ioc容器不管理多例的Bean,只负责创建。

Spring与其他框架进行整合的时候使用的就是FactoryBean来创建对象到IOC容器中。

--ColorFactoryBean代码

public class ColorFactoryBean implements FactoryBean<Green> {
@Override
public Green getObject() throws Exception {
return new Green();
} @Override
public Class<?> getObjectType() {
return Green.class;
} @Override
public boolean isSingleton() {
return true;
}
}

--SpringConfig代码

@Configuration
public class SpringConfig { @Bean
public ColorFactoryBean colorFactoryBean() {
return new ColorFactoryBean();
}
}

--单元测试

@Test
public void testApplicationContext2() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Object bean = context.getBean("colorFactoryBean");
System.out.println(bean);
System.out.println(bean.getClass());
}

--测试结果

通过结果我们可以发现,ioc容器确实有ColorFactoryBean这个对象,但是这个对象的本质是一个Green,即是我们需要创建到ioc容器中的bean。因此我们可以得出结论,只要实现了FactoryBean接口的类,spring都会执行它的getObject方法,将创建的对象放入到ioc容器中,spring和第三方框架的整合靠的就是FactoryBean。

更多详细内容参考这里

【Spring Framework】Spring入门教程(四)注册Bean到IOC容器的更多相关文章

  1. 无废话ExtJs 入门教程四[表单:FormPanel]

    无废话ExtJs 入门教程四[表单:FormPanel] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在窗体里加了个表单.如下所示代码区的第28行位置,items:form. ...

  2. PySide——Python图形化界面入门教程(四)

    PySide——Python图形化界面入门教程(四) ——创建自己的信号槽 ——Creating Your Own Signals and Slots 翻译自:http://pythoncentral ...

  3. Elasticsearch入门教程(四):Elasticsearch文档CURD

    原文:Elasticsearch入门教程(四):Elasticsearch文档CURD 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接: ...

  4. RabbitMQ入门教程(四):工作队列(Work Queues)

    原文:RabbitMQ入门教程(四):工作队列(Work Queues) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:/ ...

  5. JasperReports入门教程(四):多数据源

    JasperReports入门教程(四):多数据源 背景 在报表使用中,一个页面需要打印多个表格,每个表格分别使用不同的数据源是很常见的一个需求.假如我们现在有一个需求如下:需要在一个报表同时打印所有 ...

  6. Spring Cloud 入门教程(四): 分布式环境下自动发现配置服务

    前一章, 我们的Hello world应用服务,通过配置服务器Config Server获取到了我们配置的hello信息“hello world”. 但自己的配置文件中必须配置config serve ...

  7. 四、Spring中使用@Conditional按照条件注册Bean

    以前其实是写过@Condtional注解的笔记的,这里附上链接: Spring中的@conditional注解 但已经忘记的差不多了,所以今天再重新学习下,可以互补着学习 @Contional:按照一 ...

  8. Spring 5:以函数式方式注册 Bean

    http://www.baeldung.com/spring-5-functional-beans 作者:Loredana Crusoveanu 译者:http://oopsguy.com 1.概述 ...

  9. Spring系列11:@ComponentScan批量注册bean

    回顾 在前面的章节,我们介绍了@Comfiguration和@Bean结合AnnotationConfigApplicationContext零xml配置文件使用Spring容器的方式,也介绍了通过& ...

随机推荐

  1. OpenXml SDK学习笔记(4):设置文件级别的样式

    观察上一段日记最后的代码: 这里的样式基本可以理解为行内CSS.那么既然有行内的样式,就肯定有外部的样式.那这部分就对应笔记1里说的style.xml文件.这个文件对应的是Document.MainD ...

  2. 博主日常工作中使用的shell脚本分享

    前言: 今天给大家分享一篇在我工作中常用的一个shell脚本,里面有一些我们常用到的shell操作.该脚本用于本地电脑和服务器交互上,实现以下功能: 自动拉取自己个人电脑上的源码到服务器上yocto包 ...

  3. php 图像和水印

    生成图像 $img = imagecreate(400,400); imagecolorallocate($img,255,255,255); imageellipse($img,200,200,50 ...

  4. ICCV2021 | Vision Transformer中相对位置编码的反思与改进

    ​前言  在计算机视觉中,相对位置编码的有效性还没有得到很好的研究,甚至仍然存在争议,本文分析了相对位置编码中的几个关键因素,提出了一种新的针对2D图像的相对位置编码方法,称为图像RPE(IRPE). ...

  5. OWASP-Top5-(Security Misconfiguration 安全配置错误)

    概述 从上一版的第 6 位开始,90% 的应用程序都经过了某种形式的错误配置测试.随着更多转向高度可配置的软件,看到这一类别上升也就不足为奇了.值得注意的CWE包括CWE-16 Configurati ...

  6. [NOIP2017 提高组] 逛公园

    考虑先做一个\(dp\),考虑正反建图,然后按0边拓扑,然后按1到这里的最小距离排序,然后扩展这个\(f_{i,j}\),即多了\(j\)的代价的方案数.

  7. SSRF的原理和防范

    背景 最近做的安全测评主要是SSRF,发现自己在这一块有挺大知识盲点,抓紧补一下. 1.介绍 SSRF(Server-Side Request Forgery:服务器端请求伪造),是一种攻击者利用服务 ...

  8. 【samtools】运行报错: error while loading shared libraries:libcrypto.so.1.0.0或libncurses.so.5或libtinfow.so.5

    samtools用conda安装后,总是出现共享库缺失的报错.即便你刚安装samtools时可以用,但后面在同一环境中安装其他相关软件,有可能产生了冲突,导致库替换,因而报错. 避免这种情况,可能最好 ...

  9. miRNA分析--数据过滤(一)

    miRNA 数据过滤我使用cutadapt 1 cutadapt -a AGATCGGAAGAGCACACGTCT -m 15 -q 20 --discard-untrimmed -o outname ...

  10. ggplot 局部放大

    需要安装包:ggforce,下面以R自带数据做局部放大演示. require(ggplot2) require(ggforce) require(reshape2) data(CO2) co2< ...