Зачем начинать смотреть на исходный код весеннего
Я писал код на полпути через карьеру почти полтора года. Я использую Spring Framework с тех пор, как начал работать. Хотя я могу использовать его и создавать его, я часто не понимаю принципов, таких как: как Spring управляет транзакциями, как обрабатывает запросы Springmvc и как реализуется AOP ... это заставляет людей чувствовать себя очень неловко, поэтому начинайте медленно изучать исходный код весны, прочитав книгу !!!
Как эффективно просмотреть исходный код
Мой ответ состоит в том, чтобы посмотреть на исходный код с конкретными вопросами, в противном случае очень легко застрять в данных исходного кода, а затем вы упадете. Наконец, вы узнаете, что вы читали в течение долгого времени.
введение
Spring-это структура на уровне дизайна с открытым исходным кодом, которая решает проблему свободной связи между слоем бизнес-логики и другими уровнями и интегрирует идеи программирования, ориентированные на интерфейс, на протяжении всего системного приложения. Это также один из основных навыков в Java Work ...
Поскольку он записывает процесс анализа исходного кода Spring, я не буду подробно останавливаться на подробном использовании.
Основной код
<Depective> <groupid> org.springframework </GroupId> <strifactid> Spring-context </artifactid> <sersive> 5.0.2.release </version> </gethyseriation>
Использование
Приложение открытого класса {public static void main (string [] args) {beandefinitionregistry beanfactory = new DefletableBeanbeanBeanfactory (); XmlbeandefinitionReader Reader = new XmlBeanDefinitionReader (BeanFactory); ClassPathresource resource = new ClassPathresource ("bean.xml"); // Точка входа для всей загрузки ресурса. reader.loadbeandefinitions (ресурс); }}Дешифрование
Default -stistablebeanfactory - это реализация по умолчанию регистрации и загрузки Spring. Его можно назвать предком во всем шаблоне IOC весны.
Отслеживая по умолчанию stistablebeanfactory, вы можете найти следующие кодовые блоки. Какова цель этого дизайна?
public Abstractautowirecapablebeanfactory () {super (); игнорируется egineDependencyInterface (beannameaware.class); игнорируется eginePendencyInterface (beanfactoryaware.class); игнорировать eginePendencyInterface (beanclassloaderaware.class);}Например, когда есть атрибут B в A, Spring автоматически создаст экземпляры B, если будет обнаружено, что атрибут B не создается при получении атрибута A. Это также важная функция, представленная весной. В некоторых случаях B не будет инициализирован, например, внедрение интерфейса Beannameaware.
Spring представляет это: при автоматической сборке игнорируйте заданный интерфейс зависимости, такой как анализ зависимости регистрации контекста приложения с помощью других методов, аналогично инъекции BeanFactory через BeanFactoryAware или инъекцию ApplicationContext через ApplicationContextAware.
Управление ресурсами
Интерфейс ресурса используется для управления файлами, URL, классом и другими ресурсами. Ресурс отвечает за чтение файла конфигурации, то есть инкапсуляция файла конфигурации в ресурс, а затем передает его XMLBeanDefinitionReader для обработки.
XML -диапазон
XmlbeandefinitionReader - это реализация считывания, анализа и регистрации Spring Resource, и мы должны сосредоточиться на этом классе.
Track reader.loadBeanDefinitions(resource); , мы можем увидеть следующий базовый код (исключить комментарии и исключить исключения).
public int loadbeandefinitions (incodedresource oncodedresource) бросает BeandefinitionStoreException {try {inputStream inputStream = inCodEdresource.getResource (). getInputStream (); try {inputSource inputSource = new InputSource (inputStream); if (encoderSource.getEncoding ()! = null) {inputSource.setEncoding (encoDresource.getEncoding ()); } return doloadbeandefinitions (inputSource, ondedresource.getresource ()); } наконец {inputStream.close (); }}}Приведенный выше код сначала выполнил операцию по кодированию на ресурсе с целью беспокоиться о проблеме кодирования в XML
Если вы соблюдаете тщательно InputSource inputSource = new InputSource(inputStream); На самом деле его имя пакета на самом деле является org.xml.sax, поэтому мы можем сделать вывод, что Spring использует Sax Sacksing и использует inputsource, чтобы решить, как читать файлы XML.
Наконец, подготовленные данные передаются в реальную основную обработку с помощью параметров doLoadBeanDefinitions(inputSource, encodedResource.getResource())
Получите документ
1. doLoadBeanDefinitions(inputSource, encodedResource.getResource()); , опустите несколько уловов и комментариев
Защищенные int doloadbeandefinitions (inputsource inputsource, ресурс ресурса) выбрасывает BeandefinitionStoreException {try {Document DOC = doloadDocument (inputSource, resource); return Registerbeandefinitions (doc, ресурс); }} 2. doLoadDocument(inputSource, resource);
Защищенный документ doloaddocument (inputsource inputsource, resource resource) выбрасывает exection {return this.documentloader.loaddocument (inputSource, getEntityResolver (), this.errorHandler, getValidationmodeforresource (resource), isnamespaceare ());Во -первых, вы можете получить режим проверки (DTD или XSD) файла XML через getValidationModeforResource. Вы можете установить метод проверки самостоятельно. По умолчанию validation_auto включена, то есть режим проверки автоматически получается. Прочитайте файл XML через InputStream и проверьте, содержит ли он слова Doctype. Если он содержит его, это DTD, в противном случае он вернет XSD.
Общие шаблоны проверки файлов XML:
Общедоступный класс XmlvalidationModedetector { /*** указывает на то, что должна использоваться валидация DTD (мы обнаружили объявление «doctype»). */ public static final int validation_dtd = 2; /*** Указывает, что должна использоваться валидация XSD (не обнаружил объявления «doctype»). */ public static final int validation_xsd = 3; public int detectValidationMode (InputStream InputStream) бросает ioException {}} Параметр EntityResolver участвует в this.documentLoader.loadDocument Метод
Общедоступный документ LoadDocument (inputSource inputSource, EntityResolver EntityResolver, ErrorHandler errorHandler, int validationMode, Boolean именам Spaceaware) Throws Exception {}Что такое EntityResolver? Официальное объяснение: если приложение SAX необходимо реализовать пользовательскую обработку внешних объектов, оно должно реализовать этот интерфейс и зарегистрировать экземпляр с помощью Sax Drive, используя метод SetentityResolver. То есть для анализа XML Sax сначала прочтет объявление о документе XML и поиск соответствующего определения DTD в соответствии с объявлением, чтобы проверить документ, правила поиска по умолчанию (то есть, загрузка сети, загрузка определения DTD через адрес DTD URI, объявленные XML) и выполнить аутентификацию. Процесс загрузки - это долгий процесс, и когда сеть недоступна, здесь сообщается об ошибке, поскольку соответствующий DTD не был найден.
Функция EntityResolver заключается в том, что сам проект может предоставить метод поиска объявлений DTD, то есть программа реализует процесс поиска DTD, что позволяет избежать поиска соответствующих объявлений через сеть.
3. PentityResolver принимает два параметра:
Общедоступный абстрактный входной сигнал разрешения (String publicId, String SystemID) бросает сакссапление, ioException;
3.1 Определить файл bean.xml с содержимым следующим образом (режим XSD)
<? xml version = "1.0" Encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: schemalocation = "http://www.springframework.org/schema/beans.xsd"> </beans>
Проанализировано к следующим двум параметрам:
3.2 Определите файл bean.xml, с содержимым следующим образом (режим DTD)
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Beans public "-// Spring // dtd bean 2.0 // en" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> </beans>
Проанализировано к следующим двум параметрам:
3.3 Spring использует DelegatingEntityResolver для анализа EntityResolver
public Class DelegatingEntityResolver {@Override @nullable public inputSource ResolveEntity (String publicId, @nullable String SystemId) Throws SaxException, ioException {if (SystemId! = null) {if (SystemId.Endswith (dtd_suffix)) {return.dtdresolver.ResOlevity (dtd_suffix)) {return.dtdresolver.ResolveStiety (dtd_suffix)) } else if (systemId.endswith (xsd_suffix)) {return this.schemaresolver.resolveentity (publicid, systemid); }} return null; }}Мы можем видеть, что разные анализаторы используются для разных режимов
Зарегистрировать боб
После прочтения проверки анализа XML, продолжайте отслеживать код и посмотреть, как Spring Registers Information Beans на основе документа
Public Class XmlbeanDefinitionReader {public int RegisterBeandefinitions (документ DOC, ресурс ресурса) Throws BeanDefinitionStoreException {// Создание документов BeanDefinitionDocumentReader DocumentReader = createBeanDefinitionDocumentReader (); // Записать количество BeAndefinitions до статистики int countbefore = getRegistry (). GetBeanDefinitionCount (); // Зарегистрировать Beandefinition DocumentReader.RegisterBeanDefinitions (doc, createReadercontext (ресурс)); // Записать количество загруженных бендефиниций на этот раз return getRegistry (). GetBeanDefinitionCount () - countbebefore; }}При регистрации бобов сначала используйте класс BeandefinitionParserDelegate, чтобы определить, является ли это пространством имен по умолчанию. Реализация состоит в том, чтобы определить, равна ли URI пространства имен URI: URI по умолчанию:
Public Class BeandefinitionParserDelegate {public Static Final String Beans_Namespace_uri = "http://www.springframework.org/schema/beans"; public boolean isdefaultnamespace (@nullable string namespaceuri) {return (! stringutils.haslength (namespaceuri) || beans_namespace_uri.equals (namespaceuri)); }} Отслеживание documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); , где DOC преобразуется через LoadDocument в предыдущем блоке кода. Основная цель этого метода - извлечь корневые узлы (бобы)
открытый класс DefaultBeanDefinitionDocumentReader {@Override public void registerBeanBeanDefinitions (документ DOC, XmlReaderContext ReaderContext) {this.readercontext = readerContext; logger.debug ("Загрузка определений бобов"); Элемент root = doc.getDocumentElement (); doregisterbeandefinitions (корень); }} Отслеживайте doRegisterBeanDefinitions(root) , и мы увидим следующий поток обработки
Protected void doregisterbeandefinitions (letle Root) {// ... String profilespec = root.getAttribute (profile_attribute); // ... // пустая реализация preprocessxml (root); parsebaindefinitions (root, this.delegate); // пустая реализация postprocessxml (root); this.delegate = parent;}Во -первых, профилируйте профиль (более распространенным способом игры является то, что объекты бобов, инициализированные различными профилями, разные, поэтому они реализуют несколько сред)
В следующем анализе используется режим метода шаблона, где Preprocessxml и Postprocessxml являются пустыми методами, так что последующие подклассы могут выполнять некоторую обработку до и после анализа. Просто переопределите эти два метода.
Анализировать и зарегистрировать Beandefinition, эта часть кода относительно проста
открытый класс DefaultBeanDefinitionDocumentReader { / *** Решить другие узлы под импортом корневого узла »,« Псевдоним »,« Бин ».* @param root node node* / protected void parsebaindefinitions (element root, beandefinitionPar root.getchildnodes (); Delegate.parsecustomelement (ele); ImportBeandefinitionResource (ELE); Nested_beans_element)) {// Recurse Doregisterbeandefinitions (ELE); Delegate.parsebaindefinitionElement (ELE); Catch (BeandefinitionStoreException Ex) Делегируйте метод ParseBeanDefinitionElement в классе BeandefinitionParserDelegate для анализа элементов и верните экземпляр BeAndefinitionholder Type Bdholder (включая различные атрибуты класса файлов конфигурации, имя, идентификатор, псевдоним и т. Д.)
Когда возвращаемый BDHolder не пуст, если в детском узле есть пользовательский атрибут метки по умолчанию, пользовательская метка снова проанализируется и снова проанализируется, а затем BeanDefinitionReaderUtils.registerBeanDefinition(); Регистрирует Bdholder и отправляет регистрационное мероприятие, информируя соответствующую бобов прослушивания, что регистрация была успешной.
Суммировать
После нескольких неизвестных осенью, зимы, весны и лета все будет следовать за тем, что вы хотите ...
Хорошо, вышеупомянутое содержимое этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.
Скажите что-то
Полный текстовый код: https://gitee.com/battcn/battcn-spring-source/tree/master/chapter1 (локальная загрузка)