Другие основные статьи по Java:
Базовое изучение Java (справочник)
Исходный код Spring слишком велик, для нетехнического человека первое время будет очень сложно, поэтому я решил читать его модуль за модулем, и записал те статьи, которые показались мне очень хорошими в процессе обучения. Рекомендуется сначала прочитать рекомендуемый блог, а затем прочитать мое дополнение.Текущая версия Spring 4.3.18
Spring читает пользовательский разбор XML-файла
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
фокус
Процесс запуска всего контейнера находится в методе шаблона refresh() класса AbstractApplicationContext.
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();
}
}
}
В центре внимания следующего объясненияobtainFreshBeanFactory()
Сюда.
Рекомендуемый блог
- Тщательно изучите контейнер Spring с помощью чтения исходного кода и диаграмм последовательности.: порядок чтения этой статьи очень хороший. Она соответствует порядку выполнения кода, и есть диаграмма последовательности, помогающая в обучении. Тем не менее, я все еще немного сбит с толку, читая эту статью, главным образом потому, что она не достаточно для некоторых подробностей, и резюме является относительно грубым. Его следует изучать вместе со следующими статьями.
- Анализ исходного кода Spring Ioc (1) -- Загрузка контейнера Spring Ioc: В этой серии четыре главы, и детали относительно ясны. Он разделен на три модуля для объяснения, и есть много резюме и народных описаний методов, которые легче понять. Недостаток в том, что порядок недостаточно хорош, часто перескакивает с одного места на другое.
Суммировать
Я потратил время, чтобы перерисовать диаграмму последовательности, но процесс был слишком долгим, а качество изображения всего процесса было не очень хорошим. Поэтому я нарисовал и общую, и локальную временные диаграммы, чтобы все могли сравнить.
Ниже приводится текстовое дополнение технологического процесса всей схемы последовательности:
SpringMain->ClassPathXmlApplicationContext: new ClassPathXmlApplicationContext("applicationContext.xml");
ClassPathXmlApplicationContext->AbstractRefreshableConfigApplicationContext: setConfigLocations()
AbstractRefreshableConfigApplicationContext->ClassPathXmlApplicationContext: return
ClassPathXmlApplicationContext->AbstractApplicationContext: refresh()
AbstractApplicationContext->AbstractApplicationContext: obtainFreshBeanFactory()
AbstractApplicationContext->AbstractRefreshableApplicationContext: refreshBeanFactory()
AbstractRefreshableApplicationContext->AbstractXmlApplicationContext: loadBeanDefinitions()
AbstractXmlApplicationContext->AbstractXmlApplicationContext: loadBeanDefinitions()
AbstractXmlApplicationContext->AbstractBeanDefinitionReader: reader.loadBeanDefinitions(configLocations);
AbstractBeanDefinitionReader->AbstractBeanDefinitionReader: counter += loadBeanDefinitions(location);
AbstractBeanDefinitionReader->AbstractBeanDefinitionReader: return loadBeanDefinitions(location, null);
AbstractBeanDefinitionReader->XmlBeanDefinitionReader: int loadCount = loadBeanDefinitions(resource);
XmlBeanDefinitionReader->XmlBeanDefinitionReader: doLoadBeanDefinitions()
XmlBeanDefinitionReader->XmlBeanDefinitionReader: registerBeanDefinitions()
XmlBeanDefinitionReader->DefaultBeanDefinitionDocumentReader: registerBeanDefinitions(doc, createReaderContext(resource));
DefaultBeanDefinitionDocumentReader->DefaultBeanDefinitionDocumentReader: doRegisterBeanDefinitions()
DefaultBeanDefinitionDocumentReader->DefaultBeanDefinitionDocumentReader: parseBeanDefinitions()
DefaultBeanDefinitionDocumentReader->DefaultBeanDefinitionDocumentReader: parseDefaultElement()
DefaultBeanDefinitionDocumentReader->DefaultBeanDefinitionDocumentReader: processBeanDefinition()
DefaultBeanDefinitionDocumentReader->BeanDefinitionParserDelegate: parseBeanDefinitionElement()
BeanDefinitionParserDelegate->BeanDefinitionParserDelegate: parseBeanDefinitionElement(ele, beanName, containingBean);
note right of BeanDefinitionParserDelegate: parsePropertyElements(ele, bd);
BeanDefinitionParserDelegate->DefaultBeanDefinitionDocumentReader: return new BeanDefinitionHolder
DefaultBeanDefinitionDocumentReader->BeanDefinitionParserDelegate: decorateBeanDefinitionIfRequired
DefaultBeanDefinitionDocumentReader->BeanDefinitionReaderUtils: registerBeanDefinition
BeanDefinitionReaderUtils->DefaultListableBeanFactory: registerBeanDefinition
note right of DefaultListableBeanFactory: this.beanDefinitionMap.put(beanName, beanDefinition);
note right of DefaultListableBeanFactory: this.beanDefinitionNames.add(beanName);
DefaultListableBeanFactory->DefaultBeanDefinitionDocumentReader: return
DefaultBeanDefinitionDocumentReader->AbstractApplicationContext: obtainFreshBeanFactory() is over,return DefaultListableBeanFactory
- существует
parsePropertyElements(ele, bd);
Когда значение атрибута класса помещается в bean-компонент и возвращается BeanDefinitionHolder. - существует
this.beanDefinitionNames.add(beanName);
иthis.beanDefinitionMap.put(beanName, beanDefinition);
Когда первый должен поместить beanName в очередь, последний должен поместить BeanDefinition в карту, и на этом регистрация завершена. При более позднем создании экземпляра BeanDefinition в beanDefinitionMap извлекается и создается один за другим.
заключить:
- ApplicationContext делегирует работу по синтаксическому анализу файла конфигурации BeanDefinitionReader, а затем BeanDefinitionReader считывает файл конфигурации как документ xml, а затем делегирует его BeanDefinitionDocumentReader.
- Компонент BeanDefinitionDocumentReader действует как маршрут на основе пространства имен и имени элемента элемента xml.Фактическая работа по синтаксическому анализу делегируется для завершения BeanDefinitionParserDelegate.
- После завершения синтаксического анализа BeanDefinitionParserDelegate он вернет BeanDefinitionHolder в BeanDefinitionDocumentReader, где он будет делегирован в DefaultListableBeanFactory для завершения регистрации компонента.
- XmlBeanDefinitionReader (подсчет, разбор XML-документов), BeanDefinitionDocumentReader (использование XML-документов, разбор и регистрация), BeanDefinitionParserDelegate (фактическая работа по разбору). Видно, что в процессе парсинга бинов разделение труда между этими тремя компонентами относительно четкое, и каждый выполняет свои обязанности.
метод getBean
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
JSONArray person = (JSONArray) context.getBean("aaa");
Рекомендуемый блог
- [Изучение исходного кода Spring] getBean (включено): Порядок этой статьи лучше, удобно в первый раз смотреть исходники и следовать шагам Недостаток в том, что меньше разговоров и нет резюме.
- Полная интерпретация исходного кода GetBean: В этой статье обобщается многое.Недостаток в том, что порядок структуры беспорядочный.Я добавлю порядок ниже.
- Анализ исходного кода контейнера Spring IOC — получение одноэлементного компонента
Пополнить
[Изучение исходного кода Spring] getBean (включено)один изBeanDefinitionParseDelegate #parseBeanDefinitionAttributes
метод, место выполнения этого метода, когда пользовательский синтаксический анализ xml читается выше, запустите, чтобыBeanDefinitionParserDelegate #parseBeanDefinitionElement
метод, как показано ниже
блок-схема
Полная интерпретация исходного кода GetBeanЭта статья более хаотична, я трачу время на то, чтобы перерисовать следующий график, и в статье больше шансов понять:
Дополнение к тексту временной диаграммы:
SpringMain-> AbstractBeanFactory: getBean
AbstractBeanFactory-> AbstractBeanFactory#doGetBean: doGetBean
AbstractBeanFactory#doGetBean-> DefaultSingletonBeanRegistry: getSingleton(beanName)
AbstractBeanFactory#doGetBean-> AbstractBeanFactory#getObjectForBeanInstance: getObjectForBeanInstance
AbstractBeanFactory#doGetBean-> AbstractBeanFactory#getMergedLocalBeanDefinition: getMergedLocalBeanDefinition
AbstractBeanFactory#getMergedLocalBeanDefinition-> AbstractBeanFactory#getMergedLocalBeanDefinition: getMergedBeanDefinition
AbstractBeanFactory#doGetBean-> DefaultSingletonBeanRegistry: registerDependentBean
AbstractBeanFactory#doGetBean-> DefaultSingletonBeanRegistry: getSingleton
DefaultSingletonBeanRegistry-> DefaultSingletonBeanRegistry: beforeSingletonCreation
AbstractBeanFactory#doGetBean-> AbstractAutowireCapableBeanFactory#createBean: createBean
AbstractAutowireCapableBeanFactory#createBean-> AbstractAutowireCapableBeanFactory#doCreateBean: doCreateBean
AbstractAutowireCapableBeanFactory#doCreateBean-> AbstractAutowireCapableBeanFactory#createBeanInstance: createBeanInstance
AbstractAutowireCapableBeanFactory#createBeanInstance-> AbstractAutowireCapableBeanFactory#instantiateBean: instantiateBean
AbstractAutowireCapableBeanFactory#instantiateBean->SimpleInstantiationStrategy: instantiate
AbstractAutowireCapableBeanFactory#doCreateBean-> AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors: applyMergedBeanDefinitionPostProcessors
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors-> AutowiredAnnotationBeanPostProcessor: postProcessMergedBeanDefinition
AutowiredAnnotationBeanPostProcessor-> AutowiredAnnotationBeanPostProcessor: findAutowiringMetadata
AutowiredAnnotationBeanPostProcessor-> AutowiredAnnotationBeanPostProcessor: buildAutowiringMetadata
AbstractAutowireCapableBeanFactory#doCreateBean-> AbstractAutowireCapableBeanFactory#populateBean: populateBean
AbstractAutowireCapableBeanFactory#populateBean-> AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues: postProcessPropertyValues
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues-> InjectionMetadata: inject.
note right of InjectionMetadata: @Resource
AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues-> AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement: inject
note right of AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement: @Autowired&@Value
AbstractAutowireCapableBeanFactory#populateBean-> AbstractAutowireCapableBeanFactory#populateBean: applyPropertyValues
существуетAutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
В этом методе Spring создаст разные классы для сохранения и возврата в соответствии с различными аннотациями, такими как @Resource или @AutoWired. Различные классы, созданные здесь, будут вInjectionMetadata #inject
Когда он сработает, он вызовет методы внедрения разных классов для внедрения свойств.
круговая зависимость
Рекомендуемый блог
- инъекция пружинной зависимости - циклические зависимости
- Анализ исходного кода контейнера Spring IOC — решение циклических зависимостей
- Понимание циклических ссылок Spring (круговые зависимости)
Суммировать
Кэш третьего уровня
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
тайник | использовать |
---|---|
singletonObjects | Используется для хранения полностью инициализированных bean-компонентов, bean-компоненты, взятые из этого кеша, могут использоваться напрямую. |
earlySingletonObjects | Содержит исходный объект компонента (свойства еще не заполнены), используемый для разрешения циклических зависимостей. |
singletonFactories | Храните объекты bean factory для разрешения циклических зависимостей |
Вот три таких примера. A зависит от B (B не зависит от A)
Кэш L1 A зависит от B && B зависит от A
Кэш L3 A зависит от B && B зависит от A + B зависит от C && C зависит от A