文章目录

  • ​​一、方式一​​
  • ​​二、方式二​​
  • ​​三、方式三​​
  • ​​四、总结​​



在Spring源码中,Spring会先将类扫描为一个一个的BeanDefinition,用于存放Bean的一些基本信息,简称为Bean的定义信息。后续生成完整Bean时,直接从该集合中获取。



该集合在DefaultListableBeanFactory类中,是一个十分重要的类。

通过BeanDefinitionReader获取BeanDefinition的三种不同方式_xml


前期准备:

实体类

//在使用前两种方式时不需要添加注解,使用包扫描时需要添加注解
//@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"));

}
}

三步:

  1. 初始化Spring容器
  2. 通过容器创建注解型的BD读取器
  3. 将我们的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"));
}
}

步骤三步:

  1. 初始化Spring容器
  2. 通过配置文件创建XML类型的BD读取器,
  3. 完成将配置文件中的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"));
}
}

步骤三步:

  1. 初始化Spring容器
  2. 通过容器创建扫描型的BD读取器
  3. 配置对应的扫描路径
  4. 对被目标实体添加对应的注解


四、总结

以上三种方式,可以分别对应我们将Bean添加到Spring容器中的不同方式。直接将实体类注册为Bean;通过xml配置文件注册为Bean;配置扫描路径注册Bean。

不难发现,我们在初始化Spring容器时并没有指定对应的配置文件(xml方式除外)。以前我们配置Spring容器都是添加一个AppConfig.java的配置文件,然后通过@ComponentScan与@Component的方式去扫描Bean,或者是通过@Bean的方式去注册Bean。以上的方式就可以理解为两种方式的编程式写法。当然目的都是相同的,只是写法不同。

明白BeanDefinition的含义、来源、用途,对应理解Spring源码起着至关重要的作用。