Spring載入過程及核心類
阿新 • • 發佈:2019-12-31
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。