Предисловие
В предыдущем разделе «Дешифрование пружины» - Анализ тегов по умолчанию, мы сосредоточены на анализе того, как Spring анализирует теги по умолчанию. Таким образом, эта глава продолжает объяснять анализ маркировки метки, сосредотачиваясь на том, как проанализировать пользовательские теги. Без лишних слов давайте посмотрим на подробное введение.
Пользовательские теги
Перед объяснением пользовательского анализа тегов, пожалуйста, посмотрите, как настроить теги
Определите XSD -файл
Определите файл XSD для описания содержимого компонента
<? xml version = "1.0" Encoding = "utf-8"?> <xsd: schema xmlns = "http://www.battcn.com/schema/battcn" xmlns: xsd = "http://www.w3.org/2001/xmlschema" xmlns: beans = "http://www.springframework.org/schema/beans" namespace = "http://www.springframework.org/schema/beans"/> <xsd: inement = "Приложение"> <xsd: комплекстип> <xsd: ComplexContent> <xsd: extension base = "beans: udifiedtype"> <xsd: attule name = "name =" name "xs =" xs "string:" string "= rase" string: "string"> rate "string:" string "> rase" string: "string". </xsd: endension> </xsd: ComplexContent> </xsd: комплекстип> </xsd: element> </xsd: схема>
Определить правила анализа
1. Создайте класс для реализации интерфейса BeandefinitionParser (также может унаследовать классы, предоставленные весной), чтобы анализировать определения и определения компонентов в файле XSD.
Public Class ApplicationBeanDefinitionParser Extrasts AbstractsingsinglebeandefinitionParser {@Override Protected Class getBeanClass (элемент элемента) {// Тип принятого объекта такой, как: string name = (string) context.getbean ("battcn"); return string.class; } @Override Protected void Doparse (элемент элемента, BeandefinitionBuilder Bean) {// атрибут имени, определенное в xsd name = element.getattribute ("name"); bean.addconstructorargvalue (имя); }}Вот ApplicationBeandefinitionParser, который наследует тезисы AbstractSingBeandefinitionParser (является подклассом BeandefinitionParser). Основное внимание уделяется переопределению допарной, в нем теги XML, а затем внедрить проанализированное значение (Levin) в конструктор.
2. Создайте класс, чтобы наследовать имена пространства -handlersupport Abstract Class
Общедоступный класс Battcnnamespacehandler Extends namespacehandlersupport {@Override public void init () {RegisterBeanDefinitionParser («Приложение», New ApplicationBeandefinitionParser ()); }} Функция Battcnnamespacehandler очень проста, которая состоит в том, чтобы сообщить контейнеру Spring, что TAG <battcn:application /> должен проанализировать этот анализатор (здесь мы настраивали: ApplicationBeandefinitionParser), который отвечает за регистрацию компонентов в пружинный контейнер.
3. Напишите Spring.handlers и Spring.schemas файлы
Каталог, в котором хранится файл, находится в ресурсах/мета-инф/имя файла
Spring.handlers
http/: //www.battcn.com/schema/battcn=com.battcn.handler.battcnnamespacehandler
Spring.schemas
http/: //www.battcn.com/schema/battcn.xsd=battcn.xsd
4. Используйте пользовательские теги
Объявите файл bean.xml, определяемый следующим образом
<? xml version = "1.0" Encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: battcn = "http://www.battcn.com/schema/battcn" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.spramework.org/schema/beans/spring- http://www.battcn.com/schema/battcn http://www.battcn.com/schema/battcn.xsd "> <battcn: идентификатор приложения =" battcn "name =" levin "/> </beans>
Создайте тестовый класс. Если вы видите вывод консоли Levin Word, это означает, что пользовательская метка нормальная.
Приложение открытого класса {public static void main (string [] args) {ApplicationContext context = new ClassPathxMlapplicationContext ("bean.xml"); String name = (string) context.getbean ("battcn"); System.out.println (имя); }}5. Как показано на рисунке
Анализ исходного кода
Пользовательский портал разрешения тегов
открытый класс BeandefinitionParserDelegate {@nullable public beandefinition parsecustomelement (element ele, @nullable beandefinition содержит bd) {// Получить адрес пространства имен http://www.battcn.com/schema/battcn string namepaceuri = getnamespaceur (elnamespaceur (elnamespaceur (elnamespaceur); if (namespaceuri == null) {return null; } // namespacehandler - это приложение, зарегистрированное в настраиваемой Battcnnamespacehandler namespacehandler handler = this.readercontext.getNamespacehandlerresolver (). Resolve (namespaceuri); if (handler == null) {error («Невозможно найти пружинные имена пространства имен для xml схемы пространства имен [" + namespaceuri + "]", ele); вернуть ноль; } return handler.parse (ele, new parsercontext (this.readercontext, это, содержащее BD)); }} Как и правила разрешения тегов по умолчанию, пространство имен получается через getNamespaceURI(Node node) . Итак, где this.readerContext.getNamespaceHandlerResolver() получен. Мы отслеживаем код, и мы можем обнаружить, что когда проект запускается, все содержимое файла Meta-Inf/Spring.Handles будет анализироваться в XmlbeanDefinitionReader и хранится в Handlermapers (ConcurrentHashmap). Когда для проверки будет вызвана resolve(namespaceUri) , для сравнения будет извлечено кэшированный контент.
Общедоступный класс XmlbeandefinitionReader {public nameSpaceHandlerResolver getNamespaceHandlerResolver () {if (this.namespacehandlerresolver == null) {this.namespacehandlerresolver = createeFaultnamespacehandlerResolver (); } вернуть это.namespacehandlerresolver; }}решать
1. Загрузите указанную карту имен -пространственно -промежутка, и извлеченные имена пространство -мандлер кэшируется, а затем возвращается
открытый класс defaultnamespacehandlerresolver {@override @nullable public namespacehandler Resolve (String namespaceuri) {map <string, object> handlermappings = gethandlermappings (); // Извлечение HandlerorClassName из HandlermAppings Object HastlerorRclassName = handlerMappings.get (namespaceuri); if (handlerorclassname == null) {return null; } else if (handlerorclassname ancessionof namespacehandler) {return (namespacehandler) handlerorclassname; } else {string classname = (string) handlerorclassname; try {class <?> handlerclass = classutils.forname (classname, this.classloader); if (! namespacehandler.class.isassignablefrom (handlerclass)) {бросить новое Fatalbeanexception ("class [" + classname + "] для пространства имен [" + namespaceuri + "] не реализует интерфейс [" + namespacehandler.class.getname () + "]"); } // Найти соответствующую информацию на основе пространства имен имен имен имен имен имен и имен -имен -имен -nameshandler = (namespacehandler) beanatils.instantiateclass (handlerclass); // обработчик инициализируйте имена пространства handler.init (); handlermappings.put (namespaceuri, namespacehandler); Вернуть имена пространство -индлер; } catch (classnotfoundexception ex) {throw new FatalbeanException ("namespacehandler class [" + classname + "] для пространства имен [" + namespaceuri + "] не найден", ex); } catch (inkageError err) {throw new FatalbeanException ("Неверный класс имен -щит -сандлер [" + classname + "] для пространства имен [" + namespaceuri + "]: проблема с файлом класса Хэндлера или зависимым классом", err); }}}}Анализ тегов
После загрузки имен и инициализируется инициализированное, и Battcnnamespacehandler был инициализирован, и Battcnnamespacehandler также называет метод init() для завершения работы по инициализации. Поэтому я буду продолжать выполнять этот код: handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); конкретное решение тега.
Общедоступный класс имен и имена класса. return (parser! = null? parser.parse (element, parsercontext): null); } @Nullable private beandefinitionparser findparserforelement (элемент элемента, parsercontext parsercontext) {// Проанализируйте строку приложения localname в <battcn: Application /> .getDelegate (). GetLocalName (element); BeandefinitionParser parser = this.parsers.get (localname); if (parser == null) {parsercOntext.getReaderContext (). Fatal («не может ловить BeAndefinitionParser для элемента [" + localname + "]", element); } вернуть анализатор; }}Проще говоря, он должен найти экземпляр ApplicationBeandefinitionParser от Parsers и вызовать свой собственный метод допарной для дальнейшего анализа. Наконец, это та же процедура анализа тега по умолчанию ...
Суммировать
После нескольких неизвестных осенью, зимы, весны и лета все будет следовать за тем, что вы хотите ...
Хорошо, вышеупомянутое содержимое этой статьи. Я надеюсь, что содержание этой статьи имеет определенную справочную ценность для каждого обучения или работы. Если у вас есть какие -либо вопросы, вы можете оставить сообщение для общения. Спасибо за поддержку Wulin.com.
Скажите что-то
Полный текстовый код: https://gitee.com/battcn/battcn-spring-source/tree/master/chapter2