Sample Code
public class Provider { /** * In order to make sure multicast registry works, need to specify '-Djava.net.preferIPv4Stack=true' before * launch the application */ public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); context.start(); System.in.read(); } @Configuration /** * <1>内部包含import注解 作为初始化 * 快速入门:https://www.cnblogs.com/yichunguo/p/12122598.html */ @EnableDubbo(scanBasePackages = "provider") // @PropertySource("classpath:dubbo-provider.properties") // <2> static class ProviderConfiguration { } }
dubbo-provider configuration
dubbo.application.name=soa-promotion-provider dubbo.registry.address=127.0.0.1:9080 dubbo.registry.check=false dubbo.protocol.name=dubbo dubbo.protocol.port=23888 dubbo.protocol.threads=500 dubbo.protocol.dispatcher=message dubbo.provider.delay=-1 dubbo.provider.retries=false
Corresponding to the object is created inside the container after the config configuration
<1>EnableDubbo
@Target (ElementType.TYPE {}) // only play on the class @Retention (RetentionPolicy.RUNTIME) // retained until runtime @Inherited @Documented @EnableDubboConfig // <2> @Import annotation position @DubboComponentScan public @ interface {EnableDubbo / ** * Spring subsequent annotations can obtain DubboComponentScan api get the value provided by DubboComponentScan Spring * @return * / @AliasFor (annotation = DubboComponentScan. class , attribute = "basePackages" ) String [] scanBasePackages () default { }; / ** * DubboComponentScan annotations merger * @return */ @AliasFor(annotation = DubboComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {}; /** * DubboComponentScan的合并注解 * @return */ @AliasFor(annotation = EnableDubboConfig.class, attribute = "multiple") boolean multipleConfig() default true; }
<2>EnableDubboConfig
@Target (ElementType.TYPE {}) @Retention (RetentionPolicy.RUNTIME) @Inherited @Documented @Import (DubboConfigConfigurationRegistrar. Class ) // <. 3> initialization entry point public @ interface EnableDubboConfig { / ** * supports multiple configuration * dubbo = 192.168.0.1 .registrys.beaname1.address: 1111 * dubbo.registrys.beaname2.address = 192.168.0.1: 1111 * @return * / Boolean Multiple () default to true ; }
@Import Quickstart: Links
As can be understood as the bean is initialized spring containers will be called the @Import
DubboConfigConfigurationRegistrar
<3>DubboConfigConfigurationRegistrar
org.springframework.context.annotation.ImportBeanDefinitionRegistrar
public class DubboConfigConfigurationRegistrar the implements ImportBeanDefinitionRegistrar { / ** * * @param importingClassMetadata additional annotation contain information @Import annotation class * @param Registry can be injected through the vessel as he bean * / @Override public void registerBeanDefinitions (AnnotationMetadata importingClassMetadata, the BeanDefinitionRegistry Registry) { / ** * get EnableDubboConfig annotation information * / AnnotationAttributes the Attributes = AnnotationAttributes.fromMap ( importingClassMetadata.getAnnotationAttributes (EnableDubboConfig.class .getName ())); / ** * Get multiple defaults to true indicating whether a plurality of supports arranged config * The * / Boolean multiple attributes.getBoolean = ( "multiple" ); / ** * initialize single configuration config * < 4> Note @Import played such notes continue to read * / registerBeans (Registry, DubboConfigConfiguration.Single. class ); / ** * <4> If you open multiple configurations to initialize multiple configurations config * dubbo.applications ddd = .beanname.id * dubbo.registrys.beaname2.address = 192.168.0.1: 1111 * dubbo.registrys.beaname2.address = 192.168.0.1: 2222 * / IF (Multiple) { // Since 2.6.6 https://github.com/apache/incubator-dubbo/issues/3193 registerBeans(registry, DubboConfigConfiguration.Multiple.class); } } }
<4>DubboConfigConfiguration
public class DubboConfigConfiguration { /** * <5>定义了单个配置 每个前缀对应的 类 */ @EnableDubboConfigBindings({ @EnableDubboConfigBinding(prefix = "dubbo.application", type = ApplicationConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.module", type = ModuleConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.registry", type = RegistryConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.monitor", type = MonitorConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.provider", type = ProviderConfig.class), @EnableDubboConfigBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class) }) public static class Single { } /** * <5>定义了多个配置每个前缀对应的类 */ @EnableDubboConfigBindings({ @EnableDubboConfigBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true), @EnableDubboConfigBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true), @EnableDubboConfigBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true), @EnableDubboConfigBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true), @EnableDubboConfigBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true), @EnableDubboConfigBinding(prefix = "dubbo.providers", type = ProviderConfig.class, multiple = true), @EnableDubboConfigBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true) }) public static class Multiple { } }
<5>EnableDubboConfigBindings
/ ** * Multiple { @link EnableDubboConfigBinding} { @link Annotation} * * @Since 2.5.8 * @see EnableDubboConfigBinding * / @Target (ElementType.TYPE {}) // annotation limit to play in place @Retention (RetentionPolicy. rUNTIME) // annotation retention period is reserved here to run @Documented // identifying javadoc recorded @Import (DubboConfigBindingsRegistrar. class ) examples // Note the <3> .4 registration Department will be marked with this annotation to the container so will trigger Import <. 6> @Import public @ interface EnableDubboConfigBindings { / ** * of The value of {@link EnableDubboConfigBindings} * * @return non-null */ EnableDubboConfigBinding[] value(); }
DubboConfigBindingsRegistrar
<6>registerBeanDefinitions
com.alibaba.dubbo.config.spring.context.annotation.DubboConfigBindingsRegistrar#registerBeanDefinitions
@Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //获取EnableDubboConfigBindings注解实例 AnnotationAttributes attributes = AnnotationAttributes.fromMap( importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBindings.class.getName())); //获得values注解实例 EnableDubboConfigBinding AnnotationAttributes[] annotationAttributes = attributes.getAnnotationArray("value"); DubboConfigBindingRegistrar registrar = new DubboConfigBindingRegistrar(); registrar.setEnvironment (Environment); // Loop through EnableDubboConfigBinding Configuration <4> can be acquired at respective class mapping between prefix and for (AnnotationAttributes Element: annotationAttributes) { // < . 7> prefix and parses class mapping relationship registrar.registerBeanDefinitions (Element, Registry); } }
DubboConfigBindingRegistrar
<7>registerBeanDefinitions
com.alibaba.dubbo.config.spring.context.annotation.DubboConfigBindingRegistrar#registerBeanDefinitions
protected void registerBeanDefinitions (AnnotationAttributes Attributes, the BeanDefinitionRegistry Registry) { / ** * * prefix obtained annotation configuration such as * dubbo.application * environment.resolvePlaceholders we configured to avoid change if so placeholder * such as $ {applictionPrefix} .name = * / String prefix = environment.resolvePlaceholders (attributes.getString ( "prefix" )); / ** * Get prefix as the corresponding class is dubbo.application class is com.alibaba.dubbo.config.ApplicationConfig * generic <extends AbstractConfig> limit class must inherit AbstractConfig * / Class <? the extendsAbstractConfig> = attributes.getClass the configClass ( "type" ); / ** * whether a plurality of configuration * / Boolean Multiple attributes.getBoolean = ( "Multiple" ); / ** * <. 8> corresponding to create the bean config * / registerDubboConfigBeans (prefix, the configClass, Multiple, Registry); }
<8>registerDubboConfigBeans
private void registerDubboConfigBeans(String prefix, Class<? extends AbstractConfig> configClass, boolean multiple, BeanDefinitionRegistry registry) { //获得指定前缀的属性 如:dubbo.application.name=333 key=name value=333 Map<String, Object> properties = getSubProperties(environment.getPropertySources(), prefix); if (CollectionUtils.isEmpty(properties)) { if (log.isDebugEnabled()) { log.debug("There IS NO Property class for Binding to Dubbo config [" + configClass.getName () + "] WITHIN prefix [" prefix + + "]" ); } return ; } / ** * configuration profiles for false acquisition mltiple configuration id as beanName (id) * If you do not get the full name of the generated class #index overlay * multip is true parsing * dubbo.applications.beanname1.name = ffff * dubbo.applications.beanname2.namee = ffff2 * this time beanname1 and beanname2 will as a two-beanId * / the Set <String> = Multiple beanNames? resolveMultipleBeanNames (the Properties): Collections.singleton (resolveSingleBeanName (the Properties, configClass, Registry)); for (String beanName: beanNames) { / ** * here does not really initialize config object will only tell the bean definition of container for container initialization * After initialization of each config attributes are null * / registerDubboConfigBean (the beanName, the configClass, Registry); / ** * <. 8> DubboConfigBindingBeanPostProcessor for initialization corresponding to the properties later injected into the configuration corresponding config * / registerDubboConfigBindingBeanPostProcessor (prefix, the beanName, Multiple, Registry) ; } // Create NamePropertyDefaultValueDubboConfigBeanCustomizer to the vessel, for use DubboConfigBindingBeanPostProcessor registerDubboConfigBeanCustomizers (registry); }