Предыдущая статьяПоговорим о механизме расширения в Spring (1)болталиApplicationListener,ApplicationContextAware,BeanFactoryAwareтри механизма. Эта статья познакомитNamespaceHandlerрасширенное использование.
Я полагаю, что многие мелкие партнеры знакомы с этими категориями, в основном на основеjavaосуществленныйRPCбудут использоваться фреймворки, такие какDubbo , SOFARpcЖдать. Эта статья начинается с нескольких небольшихdemoНачните, разберитесь с основными понятиями и процессом программирования, а затем проанализируйтеSOFARpcкак используется.
NamespaceHandler
NamespaceHandlerдаSpringПредоставленный обработчик пространства имен. На картинке ниже, кроме случайного входаdemoучаствует вBridgeNameSpaceHandler, Кроме какSpringпредоставлено само собой.
beanиcontextзависимости, так что это только часть. На картинке то, что мы обычно используем, должно бытьAopNamespaceHandler.
Мы используем на основеxmlизspringПри настройке может потребоваться настроить, например,<aop:config />Такая метка, прежде чем настраивать эту метку, обычно нам нужно ввести этоaopВ пространстве имен:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd" />
Узнайте больше об АОППоговорим об АОП: представление и основные понятия, здесь не так много пояснений, дальше будет следующееПроцесс официальной документациинаписать обычайxml, окончательный эффект выглядит следующим образом:
<bridge:application id="bridgeTestApplication"
name="bridgeTestApplication"
version="1.0"
organization="bridge.glmapper.com"
owner="leishu@glmapper"/>
1. Определите файл xsd
оxsdГрамматические правила файла выходят за рамки этой статьи, и заинтересованные студенты могут составить свои собственные правила.google.
Следующий файл очень прост, определениеelementимяapplication, соответствующийbridge:applicationсерединаapplication.attributeЭто соответствующие имена атрибутов на приведенном выше дисплее эффектов.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns="http://bridge.glmapper.com/schema/bridge"
targetNamespace="http://bridge.glmapper.com/schema/bridge">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:complexType name="applicationType">
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="version" type="xsd:string"/>
<xsd:attribute name="owner" type="xsd:string"/>
<xsd:attribute name="organization" type="xsd:string"/>
</xsd:complexType>
<xsd:element name="application" type="applicationType"/>
</xsd:schema>
2. Напишите обработчик пространства имен
In addition to the schema, we need a NamespaceHandler that will parse all elements of this specific namespace Spring encounters while parsing configuration files.
написано с этимNamespaceHandlerразбирать файл конфигурации.
КонкретноNamespaceHandlerбудет основываться наschemaи имя узла, чтобы найтиBeanDefinitionParser, затем поBeanDefinitionParserВыполните конкретную аналитическую работу.
SpringПредоставляется класс реализации по умолчаниюNamespaceHandlerSupportиAbstractSingleBeanDefinitionParser, проще всего наследовать эти два класса.
Здесь по наследствуNamespaceHandlerSupportЭтот абстрактный класс готов.
public class BridgeNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("application",
new ApplicationBeanDefinitionParser());
}
}
Вот собственно просто парсер прописал, конкретныйBeanDefinitionParserбудетXMLЭлементы сопоставляются с определеннымиbeanиз.
3. Напишите BeanDefinitionParser
Здесь непосредственно через реализациюBeanDefinitionParserТо, как интерфейс определяет нашуBeanDefinitionParserКласс реализации. оAbstractSingleBeanDefinitionParserиспользуется вSPFARpcбудет задействован.
public class ApplicationBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
//beanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(ApplicationConfig.class);
beanDefinition.setLazyInit(false);
//解析id
String id = element.getAttribute("id");
beanDefinition.getPropertyValues().add("id", id);
//解析name
beanDefinition.getPropertyValues().add("name",
element.getAttribute("name"));
//解析version
beanDefinition.getPropertyValues().add("version",
element.getAttribute("version"));
//owner
beanDefinition.getPropertyValues().add("owner",
element.getAttribute("owner"));
//organization
beanDefinition.getPropertyValues().add("organization",
element.getAttribute("organization"));
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
return beanDefinition;
}
}
Здесь нам нужно понять, что когда мы начинаем анализировать пользовательские теги, мы передаемBeanDefinitionParserDelegate->parseCustomElementметод, как показано на следующем рисунке:
пройти черезeleэлемент получает текущийnamespaceUri, то есть вxsdпространства имен, определенные в , а затем делегироватьDefaultNamespaceResolverуточнитьhandler(BridgenamspaceHandler),
然后执行parseРазбор.
4. Настройте spring.handlers и spring.schmas
http\://bridge.glmapper.com/schema/bridge=
com.glmapper.extention.namespacehandler.BridgeNamespaceHandler
http\://bridge.glmapper.com/schema/bridge.xsd=META-INF/bridge.xsd
Настройка этого на самом деле сделатьSpringразборxmlКогда мы сможем воспринимать наш пользовательский элемент, нам нужно поместитьNamespaceHandlerиxsdРасположен в файле в каталог Meta-infspring.handlersиspring.schmasв файле. так что вspringНаши пользовательские теги используются в файле конфигурации. следующее:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:bridge="http://bridge.glmapper.com/schema/bridge"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://bridge.glmapper.com/schema/bridge
http://bridge.glmapper.com/schema/bridge.xsd">
<bridge:application id="bridgeTestApplication"
name="bridgeTestApplication"
version="1.0"
organization="bridge.glmapper.com"
owner="leishu@glmapper"/>
</beans>
Подтвердить, чтобы получить наш из контейнераbean:
public static void main(String[] args) {
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("classpath:bean.xml");
ApplicationConfig applicationConfig = (ApplicationConfig)
applicationContext.getBean("bridgeTestApplication");
System.out.println("applicationConfig = "+applicationConfig);
}
Пример вывода:
applicationConfig = ApplicationConfig {
id=bridgeTestApplication,
name='bridgeTestApplication',
version='1.0',
owner='leishu@glmapper',
organization='bridge.glmapper.com'
}
В целом, если мы хотим достичьxmlТеги, просто выполните следующие шаги:
- 1. Определите файл xsd
- 2. Напишите обработчик пространства имен
- 3. Напишите BeanDefinitionParser
- 4. Настройте spring.handlers и spring.schmas
Анализ использования в SOFARpc
SOFARpcсерединаrpc.xsdфайл интегрирован вsofaboot.xsdВ файле подробно видно:sofa-boot
xsdФайл не выложен здесь, он немного длинный
spring.handlers и spring.schmas
Первый взглядspring.handlersиspring.schmasКонфигурация:
http\://sofastack.io/schema/sofaboot=
com.alipay.sofa.infra.config.spring.namespace.handler.SofaBootNamespaceHandler
http\://sofastack.io/schema/sofaboot.xsd=
META-INF/com/alipay/sofa/infra/config/spring/namespace/schema/sofaboot.xsd
http\://sofastack.io/schema/rpc.xsd=
META-INF/com/alipay/sofa/infra/config/spring/namespace/schema/rpc.xsd
отspring.handlersоказатьсяNamespaceHandler : SofaBootNamespaceHandler.
SofaBootNamespaceHandler
Исходный код выглядит следующим образом.Здесь видно, что он не такой, как мы писали выше, будетBeanDefinitionParser. На самом деле здесь очень продумано.spiспособ загрузки конкретногоBeanDefinitionParser.
public class SofaBootNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
ServiceLoader<SofaBootTagNameSupport> serviceLoaderSofaBoot =
ServiceLoader.load(SofaBootTagNameSupport.class);
//SOFABoot
for (SofaBootTagNameSupport tagNameSupport : serviceLoaderSofaBoot) {
this.registerTagParser(tagNameSupport);
}
}
private void registerTagParser(SofaBootTagNameSupport tagNameSupport) {
if (!(tagNameSupport instanceof BeanDefinitionParser)) {
// log
return;
}
String tagName = tagNameSupport.supportTagName();
registerBeanDefinitionParser(tagName, (BeanDefinitionParser)
tagNameSupport);
}
}
Здесь видно, что естьReferenceDefinitionParserиServiceDefinitionParserДва класса синтаксического анализа, соответствующие ссылке на службу и представлению службы соответственно.
Ниже сReferenceDefinitionParserНапример, сначала посмотрите на его диаграмму классов:
Аналитическая работа находится вAbstractContractDefinitionParserсделано на уроке,ReferenceDefinitionParserЯ только что выполнил специальную обработку [jvm-first, jvm service].
резюме
Эта статья прошлаNamespaceHandlerУзнали, как писать наши пользовательские теги xml, изNamespaceHandlerУгол обзора можно хорошо понятьRPCОсновная часть фреймворка основана наxmlСпособы обращения к сервису и представления идей реализации. Кроме того, анализируяSOFARpc, также понимать, что в реальных инженерных компонентах дляNamespaceHandlerрасширенное использование.
Код для этой статьи:glmapper-spring-extention