注册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. 基于ABP开发框架的技术点分析和项目快速开发实现

    在我们开发各种项目应用的时候,往往都是基于一定框架进行,同时配合专用的代码生成工具,都是为了快速按照固定模式开发项目,事半功倍,本篇随笔对基于ABP开发框架的技术点进行分析和ABP框架项目快速开发实现 ...

  2. storm启动报错: InvalidTopologyException(msg:Component: [mybolt] subscribes from non-existent stream: [default] of component [es-bolt])

    storm每一个bolt在emit之后需要把数据传递到下一个bolt,所以declareOUtputFields 一定要写 默认的情况下不用加streamId,如果加了streamId,后面的bolt ...

  3. vue.js3 学习笔记 (一)——mixin 混入

    vue 2 中采用选项式API.如:data.methods.watch.computed以及生命周期钩子函数等等. mixin 混入,提供了一种非常灵活的方式,来分发 vue 组件中的可复用功能,一 ...

  4. MySQL统计总数就用count(*),别花里胡哨的《死磕MySQL系列 十》

    有一个问题是这样的统计数据总数用count(*).count(主键ID).count(字段).count(1)那个效率高. 先说结论,不用那么花里胡哨遇到统计总数全部使用count(*). 但是有很多 ...

  5. Java 多线程 - 总结概述

    概述 菜鸟教程: Java 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 多线程是多任务的一种特别的形式,但多线程 ...

  6. myeclipse自带tomcat

    安装myeclipse自带的tomcat没有在myeclipse的安装目录下,是再myeclipse指定的工作空间下 的.metadata\.plugins\com.genuitec.eclipse. ...

  7. [atAGC007E]Shik and Travel

    二分枚举答案,判定答案是否合法 贪心:每一个叶子只能经过一遍,因此叶子的顺序一定是一个dfs序,即走完一棵子树中的所有叶子才会到子树外 根据这个贪心可以dp,设$f[k][l][r]$表示仅考虑$k$ ...

  8. AotucCrawler 快速爬取图片

    AotucCrawler 快速爬取图片 今天介绍一款自动化爬取图片项目. GitHub: https://github.com/YoongiKim/AutoCrawler Google, Naver ...

  9. 从零开始学Kotlin第三课

    kotlin函数和函数式表达式的简化写法: fun main(args:Array<String>) { var result=add(2,5) println(result) ///简化 ...

  10. tomcat进行远程debug

    Windows下   进入目录下的bin目录,编辑打开startup.bat 在前面添加: SET CATALINA_OPTS=-server -Xdebug -Xnoagent -Djava.com ...