聊聊dubbo的DubboComponentScanRegistrar
序
本文主要研究一下dubbo的DubboComponentScanRegistrar
DubboComponentScanRegistrar
dubbo-2.7.3/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java
public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { Set<String> packagesToScan = getPackagesToScan(importingClassMetadata); registerServiceAnnotationBeanPostProcessor(packagesToScan, registry); registerReferenceAnnotationBeanPostProcessor(registry); } /** * Registers {@link ServiceAnnotationBeanPostProcessor} * * @param packagesToScan packages to scan without resolving placeholders * @param registry {@link BeanDefinitionRegistry} * @since 2.5.8 */ private void registerServiceAnnotationBeanPostProcessor(Set<String> packagesToScan, BeanDefinitionRegistry registry) { BeanDefinitionBuilder builder = rootBeanDefinition(ServiceAnnotationBeanPostProcessor.class); builder.addConstructorArgValue(packagesToScan); builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); AbstractBeanDefinition beanDefinition = builder.getBeanDefinition(); BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry); } /** * Registers {@link ReferenceAnnotationBeanPostProcessor} into {@link BeanFactory} * * @param registry {@link BeanDefinitionRegistry} */ private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) { // Register @Reference Annotation Bean Processor BeanRegistrar.registerInfrastructureBean(registry, ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class); } private Set<String> getPackagesToScan(AnnotationMetadata metadata) { AnnotationAttributes attributes = AnnotationAttributes.fromMap( metadata.getAnnotationAttributes(DubboComponentScan.class.getName())); String[] basePackages = attributes.getStringArray("basePackages"); Class<?>[] basePackageClasses = attributes.getClassArray("basePackageClasses"); String[] value = attributes.getStringArray("value"); // Appends value array attributes Set<String> packagesToScan = new LinkedHashSet<String>(Arrays.asList(value)); packagesToScan.addAll(Arrays.asList(basePackages)); for (Class<?> basePackageClass : basePackageClasses) { packagesToScan.add(ClassUtils.getPackageName(basePackageClass)); } if (packagesToScan.isEmpty()) { return Collections.singleton(ClassUtils.getPackageName(metadata.getClassName())); } return packagesToScan; } }
- DubboComponentScanRegistrar实现了ImportBeanDefinitionRegistrar接口定义的registerBeanDefinitions方法;它首先通过getPackagesToScan方法从AnnotationMetadata读取要扫描的包,然后再执行registerServiceAnnotationBeanPostProcessor、registerReferenceAnnotationBeanPostProcessor方法
- getPackagesToScan方法读取DubboComponentScan注解信息,获取要扫描的包;registerServiceAnnotationBeanPostProcessor方法则是通过BeanDefinitionReaderUtils.registerWithGeneratedName注册ServiceAnnotationBeanPostProcessor
- registerReferenceAnnotationBeanPostProcessor方法则是通过BeanRegistrar.registerInfrastructureBean注册ReferenceAnnotationBeanPostProcessor
DubboComponentScanRegistrarTest
dubbo-2.7.3/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrarTest.java
public class DubboComponentScanRegistrarTest { @BeforeEach public void setUp() { ConfigManager.getInstance().clear(); } @AfterEach public void tearDown() { ConfigManager.getInstance().clear(); } @Test public void test() { AnnotationConfigApplicationContext providerContext = new AnnotationConfigApplicationContext(); providerContext.register(ProviderConfiguration.class); providerContext.refresh(); DemoService demoService = providerContext.getBean(DemoService.class); String value = demoService.sayName("Mercy"); Assertions.assertEquals("Hello,Mercy", value); Class<?> beanClass = AopUtils.getTargetClass(demoService); // DemoServiceImpl with @Transactional Assertions.assertEquals(DemoServiceImpl.class, beanClass); // Test @Transactional is present or not Assertions.assertNotNull(findAnnotation(beanClass, Transactional.class)); AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext(); consumerContext.register(ConsumerConfiguration.class); consumerContext.refresh(); ConsumerConfiguration consumerConfiguration = consumerContext.getBean(ConsumerConfiguration.class); demoService = consumerConfiguration.getDemoService(); value = demoService.sayName("Mercy"); Assertions.assertEquals("Hello,Mercy", value); ConsumerConfiguration.Child child = consumerContext.getBean(ConsumerConfiguration.Child.class); // From Child demoService = child.getDemoServiceFromChild(); Assertions.assertNotNull(demoService); value = demoService.sayName("Mercy"); Assertions.assertEquals("Hello,Mercy", value); // From Parent demoService = child.getDemoServiceFromParent(); Assertions.assertNotNull(demoService); value = demoService.sayName("Mercy"); Assertions.assertEquals("Hello,Mercy", value); // From Ancestor demoService = child.getDemoServiceFromAncestor(); Assertions.assertNotNull(demoService); value = demoService.sayName("Mercy"); Assertions.assertEquals("Hello,Mercy", value); providerContext.close(); consumerContext.close(); } }
- DubboComponentScanRegistrarTest分别验证了providerContext、consumerContext
小结
- DubboComponentScanRegistrar实现了ImportBeanDefinitionRegistrar接口定义的registerBeanDefinitions方法;它首先通过getPackagesToScan方法从AnnotationMetadata读取要扫描的包,然后再执行registerServiceAnnotationBeanPostProcessor、registerReferenceAnnotationBeanPostProcessor方法
- getPackagesToScan方法读取DubboComponentScan注解信息,获取要扫描的包;registerServiceAnnotationBeanPostProcessor方法则是通过BeanDefinitionReaderUtils.registerWithGeneratedName注册ServiceAnnotationBeanPostProcessor
- registerReferenceAnnotationBeanPostProcessor方法则是通过BeanRegistrar.registerInfrastructureBean注册ReferenceAnnotationBeanPostProcessor
doc
相关推荐
ATenhong 2020-10-15
supperme 2020-09-08
doctorvian 2020-08-02
aNian 2020-08-01
kongjunlongaa 2020-06-29
Fightingxr 2020-06-26
whileinsist 2020-06-24
doctorvian 2020-06-16
XuNeely 2020-06-16
wangyangsoftware 2020-06-16
大步流星 2020-06-16
aNian 2020-06-16
gaoyongstone 2020-06-16
MartellJenkins 2020-06-11
范群松 2020-06-11
Fightingxr 2020-06-08
XuNeely 2020-06-07
大步流星 2020-06-05