spring ioc实现原理
1、一个普通的调用
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); GsonFormatBean bean = (GsonFormatBean) context.getBean("GsonFormatBean"); bean.isPalindrome(100);
1.1 分析第一步
创建一个classPathXmlApplication的context,主要的实现在abstractAppplicationContext的refresh()这个方法中
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
使用对象锁保证只有一个线程访问逻辑
第一步:
设置容器的一些全局性参数,比如closed,active等参数
第二步:
告诉父类创建一个bean工厂
刷新整个bean工厂,获取一个ConfigurableListableBeanFacotory,返回bean工厂。
刷新beanFactory
创建一个DefaultListableBeanFactory,设置一些属性,加载beanDefinition,具体的实现在abstractxmlApplicationContext、AnnotationWebConfigApplicationContext等
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
容器怎么实现加载所有的bean
两个关键的方法:
容器注册所有的beanDefinitions
解析单个bean的操作
最终生成beanDefination,也就是将xml映射成为一个bean
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------