Dubbo标签解析,因为是自己看的源码,从DubboNamespaceHandler开始看。
源码翻看基础:了解spirng自定义标签的解析。
spring自定义标签知识:
Spring允许你创建自定义的XML标签以简化和定制配置。要解析自定义Spring XML标签,你需要创建一个自定义的命名空间和标签解析器。以下是创建和解析自定义Spring XML标签的一般步骤:
-
创建自定义标签定义: 首先,你需要定义你的自定义标签。这包括创建一个XML命名空间、XSD架构文件和自定义标签的定义。通常,这些文件包括以下几个部分:
- XML命名空间声明:定义你的自定义XML命名空间以及命名空间的URL。
- XSD架构文件:定义你的自定义标签的元素、属性等详细结构。这通常是一个XSD文件。
- 自定义标签定义:定义你的自定义标签的名称、属性和元素。
-
创建标签解析器: 接下来,你需要创建一个Java类,这个类将充当自定义标签的解析器。这个类需要实现Spring的
BeanDefinitionParser
接口,通常会继承AbstractSingleBeanDefinitionParser
或AbstractBeanDefinitionParser
。你需要实现parseInternal
方法来解析标签的属性和元素,并创建相应的BeanDefinition
。 -
注册标签解析器: 在Spring的配置文件中,你需要注册你的自定义标签解析器。这通常是通过在XML配置文件中使用
<bean>
元素来完成的。 -
使用自定义标签: 现在,你可以在Spring配置文件中使用你的自定义标签。确保在XML文件的顶部引入你的命名空间,并使用你的自定义标签。
-
加载和启动Spring应用: 最后,加载和启动Spring应用程序。当Spring容器启动时,它将解析和处理你的自定义标签,创建相应的
BeanDefinition
,并将它们注册到应用程序上下文中
1.例如一个xml中定义一个自定义标签:
<
test:testBean
id
=
"testBean"
name
=
"Rob Harrop"
age
=
"23"
/>
2.对自定义标签解析
final
class
TestNamespaceHandler
extends
NamespaceHandlerSupport {
@Override
public
void
init() {
//注册parser
registerBeanDefinitionParser(
"testBean"
,
new
TestBeanDefinitionParser());
}
3.解析类:
private static class TestBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
RootBeanDefinition definition = new RootBeanDefinition();
definition.setBeanClass(CustomBean.class);
MutablePropertyValues mpvs = new MutablePropertyValues();
mpvs.add("name", element.getAttribute("name"));
mpvs.add("age", element.getAttribute("age"));
//1.设置beanDefinition的 属性 propertyValues
definition.setPropertyValues(mpvs);
//2.获取到beanDefinition的 registry
parserContext.getRegistry().registerBeanDefinition(element.getAttribute("id"), definition);
return null;
}
}
handler解析类的入口是init方法的覆盖。
下面看org.apache.dubbo.config.spring.schema.DoubleNamespaceHandler这个类的init方法。
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
registerBeanDefinitionParser("config-center", new DubboBeanDefinitionParser(ConfigCenterBean.class, true));
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class, true));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class, true));
registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.class, true));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
registerBeanDefinitionParser("annotation", new AnnotationBeanDefinitionParser());
这里有多个double的标签,我们看DubboBeanDefinitionParser类的parse方法。
看这个方法前,先熟悉一下spring解析的api。
RootBeanDefinition definition= new RootBeanDefinition();
definition.setBeanClass(getClass());
definition.setLazyInit(false);
String id=element.getAttribute("id");
if (StringUtils.isEmpty(id)) {
String name=element.getAttribute("name");
}
//给bean添加属性
definition.getPropertyValues().addPropertyValue(id, "sadf");
//是否包含一个bean
parserContext.getRegistry().containsBeanDefinition("");
//注册
parserContext.getRegistry().registerBeanDefinition(id, definition);
return definition;