1.@DubboService @DubboReference combined with Spring
Code entry: @EnableDubbo
: Start the automatic configuration of dubbo. Dubbo combined with Spring entrance
Focus on: @EnableDubboConfig
, @DubboComponentScan
@EnableDubboConfig
@DubboComponentScan
DubboComponentScanRegistrar
, theReferenceAnnotationBeanPostProcessor
class is initialized inDubboSpringInitializer#initialize
(the attribute @DubboReference injection is completed in ReferenceAnnotationBeanPostProcessor)
ReferenceAnnotationPostProcessor
is initialized when initializing the dubbo bean.
In DubboComponentScanRegistrar
, ServiceAnnotationPostProcessor
was generated and the path to be scanned was passed in
1.1 Core principles of @DubboService
ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPostProcessor (used to dynamically generate bean information)
DubboClassPathBeanDefinitionScanner
is used to scan the @DubboService
annotation
1.2 Core Principles of @DubboReference
@DubboReference attribute injection is handled in ReferenceAnnotationBeanPostProcessor. After Spring instantiates the object, it will execute
postProcessPropertyValues()
for property injection.
1.2.1 Obtain metadata
AbstractAnnotationBeanPostProcessor
Scan the fields identified by @DubboReference in each bean object through ReflectionUtils.doWithFields
1.2.2 Inject fields identified by @DubboReference
ReferenceAnnotationBeanPostProcessor#doGetInjectedBean()
3.Dubbo xml combined with Spring
Theoretical knowledge:
- Spring XML schema expansion mechanism: define bean objects and the relationships between bean objects through xml.
- .xsd file: called XML schema definition. A structural language used to describe XML documents. Developed specifications for XML files. For example: define the elements and attributes of the XML document, as well as the name, data type, etc. of the attributes.
- spring.schemas file: find the mapping relationship between schemas and xsd files
- spring.handlers file: Find the tag parsing implementation class specified by schemas (the class that implements
BeanDefinitionParser
) - Abstract
NamespaceHandler
: Provides the ability to parse schemas BeanDefinitionParser
: ProvidesElement
for parsing each schemas and generates specificBeanDefinition
- BeanDefinitionParser: parses xml nodes to generate
BeanDefinition
.
3.1 How Dubbo implements xml configuration to generate BeanDefinition
How does Spring implement xml to generate BeanDefinition?
- Write an xsd file to define custom label configuration rules.
- The spring.schemas file defines the import form of custom tags.
- Implement NamespaceHandlerSupport for custom parsing logic.
- Write the spring.handlers file to specify the implementation class of the custom tag.
How Dubbo implements XML generation of BeanDefinition (take
as an example)
- Write the dubbo.xsd file.
<!-- The tag name is service, the type is serviceType, and the associated complexType name=serviceType --> <xsd:element name="service" type="serviceType"> <xsd:annotation> <xsd:documentation><![CDATA[ Export service config ]]></xsd:documentation> <xsd:appinfo> <tool:annotation> <tool:exports type="org.apache.dubbo.config.ServiceConfig"/> </tool:annotation> </xsd:appinfo> </xsd:annotation> </xsd:element>
- Write the spring.schemas file.
http://dubbo.apache.org/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd http://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/compat/dubbo.xsd
- Write the spring.handlers file.
http://dubbo.apache.org/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler http://code.alibabatech.com/schema/dubbo=org.apache.dubbo.config.spring.schema.DubboNamespaceHandler
- Customize
DubboNamespaceHandler
, extends fromNamespaceHandlerSupport
, and resolve
into ServiceBean.- 1. Use
init()
to registerBeanDefinitionParser
during initialization - 2. Complete the parsing logic in
DubboNamespaceHandler
‘sparse()
- 1. Use
//DubboBeanDefinitionParser.parse() // Note: The code for other types of Beans is removed here, only the logic of ServiceBean is retained. private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {<!-- --> RootBeanDefinition beanDefinition = new RootBeanDefinition(); beanDefinition.setBeanClass(beanClass); beanDefinition.setLazyInit(false); String id = element.getAttribute("id"); //...omit code // Parse ServiceBean if (ServiceBean.class.equals(beanClass)) {<!-- --> String className = element.getAttribute("class"); if (StringUtils.isNotEmpty(className)) {<!-- --> RootBeanDefinition classDefinition = new RootBeanDefinition(); classDefinition.setBeanClass(ReflectUtils.forName(className)); classDefinition.setLazyInit(false); parseProperties(element.getChildNodes(), classDefinition); beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl")); } } //...omit code return beanDefinition; }
- Hand over the generated
Beandefinition
to spring for processing
tip:
- spring.schemas are mapped to local files to avoid network-less situations.
Reference documentation:
@DubboService underlying mechanism
Dubbo integrates XML
Nuggets booklet provides an in-depth analysis of Dubbo architecture design and implementation principles – Chapter 6