文章目录
- 一、方式一
- 二、方式二
- 三、方式三
- 四、总结
在Spring源码中,Spring会先将类扫描为一个一个的BeanDefinition,用于存放Bean的一些基本信息,简称为Bean的定义信息。后续生成完整Bean时,直接从该集合中获取。
该集合在DefaultListableBeanFactory类中,是一个十分重要的类。
前期准备:
实体类
//在使用前两种方式时不需要添加注解,使用包扫描时需要添加注解
//@Component
public class MoBian {
}
一、方式一
等价于@Bean
public class test02 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);
annotatedBeanDefinitionReader.register(MoBian.class);
System.out.println(context.getBean("moBian"));
}
}
三步:
- 初始化Spring容器
- 通过容器创建注解型的BD读取器
- 将我们的Bean直接注册到读取器中
二、方式二
等价于传统的ClassPathXmlApplicationContext传入配置文件
public class test02 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
// 返回注册的Bean数量
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring-test.xml");
System.out.println(context.getBean("moBian"));
}
}
步骤三步:
- 初始化Spring容器
- 通过配置文件创建XML类型的BD读取器,
- 完成将配置文件中的Bean加载到BD读取器中
三、方式三
等价于@ComponentScan+@Component的组合
public class test02 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("pers.mobian.springfirst.factorybean");
System.out.println(context.getBean("moBian"));
}
}
步骤三步:
- 初始化Spring容器
- 通过容器创建扫描型的BD读取器
- 配置对应的扫描路径
- 对被目标实体添加对应的注解
四、总结
以上三种方式,可以分别对应我们将Bean添加到Spring容器中的不同方式。直接将实体类注册为Bean;通过xml配置文件注册为Bean;配置扫描路径注册Bean。
不难发现,我们在初始化Spring容器时并没有指定对应的配置文件(xml方式除外)。以前我们配置Spring容器都是添加一个AppConfig.java的配置文件,然后通过@ComponentScan与@Component的方式去扫描Bean,或者是通过@Bean的方式去注册Bean。以上的方式就可以理解为两种方式的编程式写法。当然目的都是相同的,只是写法不同。
明白BeanDefinition的含义、来源、用途,对应理解Spring源码起着至关重要的作用。