注册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。

更多详细内容参考这里

最新文章

  1. JavaScript-计算器
  2. Linux一块网卡添加多个IP地址
  3. Linux/UNIX 定时任务 cron 详解
  4. (转)MySQL优化实例
  5. HDU 5029 Relief grain 树链剖分打标记 线段树区间最大值
  6. Linux作业控制
  7. 李洪强iOS开发Swift篇—03_字符串和数据类型
  8. JS字符串常用方法
  9. jxl读写excel的方法
  10. synchronized和vilatile
  11. EntityFramework6 用 PostgreSQL
  12. Ubuntu上CUDA和CUDNN的安装
  13. 一个爬取Bing每日壁纸的python脚本
  14. springmvc接收ajax传递的数组
  15. Just Oj 2017C语言程序设计竞赛高级组D: 字符串最大表示(next数组)
  16. 使用quartz数据库锁实现定时任务的分布式部署
  17. python记录_day14 内置函数二 迭代 二分法
  18. 使用 localeCompare 函数对中文进行排序
  19. Rest架构风格
  20. Linux命令(六) 查看文件 cat tac more less tail

热门文章

  1. dotnet 6 使用 CreateSymbolicLink 创建文件夹符号链接
  2. 力扣 - 剑指 Offer 59 - I. 滑动窗口的最大值
  3. [源码解析] PyTorch 分布式(3) ----- DataParallel(下)
  4. IDEA常用优化设置
  5. 【Azure 环境】用 PowerShell 调用 AAD Token, 以及调用Azure REST API(如资源组列表)
  6. Asp.Net Core中简单使用日志组件log4net
  7. vue的常用指令
  8. SpringCloud升级之路2020.0.x版-43.为何 SpringCloudGateway 中会有链路信息丢失
  9. 使用微软RPA工具 Power Automate自动完成重复性工作
  10. CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全