Spring加載過程及核心類

1. ClassPathXmlApplicationContext

在非web環境中,經常使用ClassPathXmlApplicationContext來建立ApplicationContextjava

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");web

1.1 繼承關係

下面以ClassPathXmlApplicationContext來看加載流程。spring

2. 加載步驟

    1. ClassPathXmlApplicationContext設置配置文件位置。
    1. AbstractApplicationContext.refresh(): 設置spring上下文環境,建立BeanFacotry並設置。
    1. AbstractRefreshableApplicationContext.refreshBeanFactory.
    1. AbstractRefreshableApplicationContext. loadBeanDefinitions, 抽象方法,由子類實現。
    1. AbstractXmlApplicationContext.loadBeanDefinitions: 讀取xml配置信息,並建立BeanDefinition註冊到Spring環境。
    1. 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的屬性。app

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等。ide

自定義ApplicationContext:spa

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;code

  • 2.實現loadBeanDefinitions;cdn

  • 3.建立BeanDefinition(AbstractBeanDefinition, RootBeanDefinition, 或 GenericBeanDefinition);xml

  • 4.經過beanDefinition.getPropertyValues().addPropertyValue設置bean的屬性;對象

  • 5.beanFactory.registerBeanDefinition註冊bean。

相關文章
相關標籤/搜索