Spring加载过程及核心类
1. ClassPathXmlApplicationContext
在非web环境中,常用ClassPathXmlApplicationContext来创建ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
1.1 继承关系

下面以ClassPathXmlApplicationContext来看加载流程。
2. 加载步骤
-
- ClassPathXmlApplicationContext设置配置文件位置。
-
- AbstractApplicationContext.refresh(): 设置spring上下文环境,创建BeanFacotry并设置。
-
- AbstractRefreshableApplicationContext.refreshBeanFactory.
-
- AbstractRefreshableApplicationContext. loadBeanDefinitions, 抽象方法,由子类实现。
-
- AbstractXmlApplicationContext.loadBeanDefinitions: 读取xml配置信息,并创建BeanDefinition注册到Spring环境。
-
- AbstractAutowireCapableBeanFactory.createBean: 由之前创建的BeanFactory创建bean对象,并设置各种属性和调用接口。
3. 核心类
- BeanDefinition: Bean的定义类, 和xml里的配置一一对应;
- BeanFacotry: Bean工厂接口;
- BeanDefinitionRegistry: BeanDefinition的注册定义接口;
- DefaultListableBeanFactory: ListableBeanFactory(extends BeanFactory)和BeanDefinition的默认实现,提供BeanDefinition注册功能;
- ApplicationContext: Spring上下文环境;
- AbstractApplicationContext: 执行refresh()方法;
- AbstractRefreshableApplicationContext: 提供抽象方法loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 用于加载BeanDefinition.
3.1 BeanDefinition

- 1.RootBeanDefinition: 普通bean。
- 2.ChildBeanDefinition: 子bean,spring内部使用,一般推荐使用GenericBeanDefinition代替;
- 3.可以调用BeanDefinitionReaderUtils.createBeanDefinition创建,会返回AbstractBeanDefinition。
3.1.1 手动创建bean的定义
public static void main(String[] args) throws ClassNotFoundException {
//1 声明BeanDefinition
BeanDefinition userDaoDefinition = new RootBeanDefinition(UserDao.class);
BeanDefinition beanDefinition = BeanDefinitionReaderUtils.createBeanDefinition(null, User33Service.class.getName(), null);
//2 创建BeanFactory,并注册beanDefinitions
beanDefinition.getPropertyValues().addPropertyValue("userDao", new RuntimeBeanReference("userDao"));
List<Integer> values = new ManagedList<>();
values.add(1);
values.add(2);
values.add(3);
beanDefinition.getPropertyValues().addPropertyValue("values", values);
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("userService", beanDefinition);
beanFactory.registerBeanDefinition("userDao", userDaoDefinition);
User33Service user33Service = (User33Service) beanFactory.getBean("userService");
System.out.println(user33Service.getUser());
}
- 1.创建BeanDefinition对象,BeanDefinition的字段,和xml中的配置节点一致;
- 2.创建DefaultListableBeanFactory对象,或实现接口BeanFactoryPostProcessor以获取到当前的beanFactory;
- 3.调用DefaultListableBeanFactory的registerBeanDefinition。
BeanDefinition中通过 beanDefinition.getPropertyValues().addPropertyValue 设置bean的属性。
3.1.2 xml标签与BeanDefinition属性类型映射:
- 属性:
- ref : RuntimeBeanReference
- value : TypedStringValue
- property的子标签:
- bean: BeanDefinitionHolder
- ref : RuntimeBeanReference
- idref : RuntimeBeanNameReference
- value : TypedStringValue
- null : TypedStringValue
- array : ManagedArray or List 代码中已经被强制转换为List
- list : ManagedList or List 代码中已经被强制转换为List
- set : ManagedSet or Set 代码中已经被强制转换为Set
- map : ManagedMap or Map 代码中已经被强制转换为Map
- props : ManagedProperties
3.2 ApplicationContext
Spring中的ApplicationContext基本都是继承自AbstractRefreshableConfigApplicationContext,比如ClassPathXmlApplicationContext,FileSystemXmlApplicationContext等。
自定义ApplicationContext:
public class MyContext extends AbstractRefreshableConfigApplicationContext {
public MyContext(){
super.addApplicationListener(new MyListener());
super.refresh();
}
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
RootBeanDefinition beanDefinition = new RootBeanDefinition(CustomService.class);
beanFactory.registerBeanDefinition("testBean", beanDefinition);
beanFactory.registerBeanDefinition("childBean", new GenericBeanDefinition(beanDefinition));
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(CustomService.class);
beanFactory.registerBeanDefinition("genericBean", genericBeanDefinition);
}
}
- 1 继承AbstractRefreshableConfigApplicationContext;
- 2 实现loadBeanDefinitions,注册bean。
3.3 实现自己的spring环境
-
1.继承AbstractRefreshableConfigApplicationContext,并在构造函数中调用super.refresh();
-
2.实现loadBeanDefinitions;
-
3.创建BeanDefinition(AbstractBeanDefinition, RootBeanDefinition, 或 GenericBeanDefinition);
-
4.通过beanDefinition.getPropertyValues().addPropertyValue设置bean的属性;
-
5.beanFactory.registerBeanDefinition注册bean。
转载自:https://juejin.cn/post/6844903990870687751