dubbo是基于spring构建和运行的,兼容spring配置。这篇说说dubbo基于spring的过程。
dubbo首先利用了从spring2.0开始的一个特性,Extensible XML authoring,扩展spring了标签功能。
关于如何利用spring扩展本身的标签,能够参考下官方介绍
https://docs.spring.io/spring/docs/3.2.18.RELEASE/spring-framework-reference/htmlsingle/#extensible-xml
根据文档的说法,须要以下4步:
1,编写xml,描述须要扩展的标签的配置属性,dubbo实现放在jar包META-INF/dubbo.xsd文件里
同时经过编写META-INF/spring.handlers文件,提供给spring,内容以下
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
xsd文件也很好编写阅读,里面有继承和嵌套的概念。
2,写一个NamespaceHandler接口实现类,dubbo的实现类是DubboNamespaceHandler
同时经过编写META-INF/spring.schemas文件,提供给spring,内容以下:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
3,编写一个(或者多个)BeanDefinitionParser实现类,用来解析扩展的元素,dubbo实现类是DubboBeanDefinitionParser,
这个类也是真正的须要本身处理的代码所在。
4,把以上组件注册给spirng,这个dubbo其实在DubboNamespaceHandler类里。html
public class DubboNamespaceHandler extends NamespaceHandlerSupport { static { Version.checkDuplicate(DubboNamespaceHandler.class); } public void init() { //设置每一个扩展标签对应解析类,并注册扩展的10个标签 registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true)); registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true)); registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true)); registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.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 DubboBeanDefinitionParser(AnnotationBean.class, true)); } }
完成以上事情,spring就能识别dubbo的扩展标签了。下面分别从代码层面看看具体实现。java
上面提到的10个扩展标签,分别对应10个配置类。类的层次关系:
主要基类是AbstractConfig和AbstractMethodConfig,而AbstractConfig又是全部类的基类。
这10个配置类中ReferenceBean,ServiceBean,AnnotationBean 3个类又都实现了若干spring接口,这3个类算是利用spring完成dubbo调用的驱动类,后面要分别看源码。node
这个类实现了BeanDefinitionParser接口,这是个spring的原生接口,里面只有一个方法
public interface BeanDefinitionParser {
BeanDefinition parse(Element element, ParserContext parserContext);
}
根据接口定义,这个方法实现,须要解析Element元素成原生的BeanDefinition类对象,而后利用
ParserContext对象的getRegistry()返回的注册器来注册解析后BeanDefinition类对象,
最后返回这个BeanDefinition类对象。下面是dubbo的实现,它主要完成spring配置到spring容器内部BeanDefinition转化过程。代码:spring
private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) { // new RootBeanDefinition 对象,做为注册和返回的对象 RootBeanDefinition beanDefinition = new RootBeanDefinition(); //设置class beanDefinition.setBeanClass(beanClass);// beanDefinition.setLazyInit(false); String id = element.getAttribute("id");//获取id if ((id == null || id.length() == 0) && required) { //没法获取id的按策略生成id String generatedBeanName = element.getAttribute("name"); if (generatedBeanName == null || generatedBeanName.length() == 0) { if (ProtocolConfig.class.equals(beanClass)) { //ProtocolConfig 类型为dubbo开头 generatedBeanName = "dubbo"; } else { generatedBeanName = element.getAttribute("interface"); } } if (generatedBeanName == null || generatedBeanName.length() == 0) { generatedBeanName = beanClass.getName(); } id = generatedBeanName; int counter = 2; //id 为name1,name2 形式,检测id 是否存在,存在id,序号自增 while (parserContext.getRegistry().containsBeanDefinition(id)) { id = generatedBeanName + (counter++); } } if (id != null && id.length() > 0) { if (parserContext.getRegistry().containsBeanDefinition(id)) { throw new IllegalStateException("Duplicate spring bean id " + id); } //利用parserContext.getRegistry()注册beanDefinition parserContext.getRegistry().registerBeanDefinition(id, beanDefinition); //这是beanDefinition id属性 beanDefinition.getPropertyValues().addPropertyValue("id", id); } //把全部protocol属性name等于id&&类型是ProtocolConfig的 // protocol 属性设置为 new RuntimeBeanReference(id),应用当前BeanDefinition if (ProtocolConfig.class.equals(beanClass)) { for (String name : parserContext.getRegistry().getBeanDefinitionNames()) { BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name); PropertyValue property = definition.getPropertyValues().getPropertyValue("protocol"); if (property != null) { Object value = property.getValue(); if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) { definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id)); } } } } else if (ServiceBean.class.equals(beanClass)) { //直接指定class的方式 String className = element.getAttribute("class"); if (className != null && className.length() > 0) { RootBeanDefinition classDefinition = new RootBeanDefinition(); //利用反射有类名获得class classDefinition.setBeanClass(ReflectUtils.forName(className)); classDefinition.setLazyInit(false); //解析property parseProperties(element.getChildNodes(), classDefinition); //把serviceBean 的ref 属性设置为指向class类 beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl")); } } else if (ProviderConfig.class.equals(beanClass)) { //proivder的配置 做为ServiceBean 的设置 parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition); } else if (ConsumerConfig.class.equals(beanClass)) { // consumer的配置 做为ReferenceBean 的设置 parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition); } Set<String> props = new HashSet<String>(); ManagedMap parameters = null; for (Method setter : beanClass.getMethods()) { String name = setter.getName(); if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(setter.getModifiers()) && setter.getParameterTypes().length == 1) { //全部只有一个参数的set方法 //set方法参数类型 Class<?> type = setter.getParameterTypes()[0]; //abCdEF --> ab-cd-ef 驼峰命名转换 - 分割 String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), "-"); props.add(property); Method getter = null; //获取 对应public getter 方法 try { getter = beanClass.getMethod("get" + name.substring(3), new Class<?>[0]); } catch (NoSuchMethodException e) { try { getter = beanClass.getMethod("is" + name.substring(3), new Class<?>[0]); } catch (NoSuchMethodException e2) { } } if (getter == null || !Modifier.isPublic(getter.getModifiers()) || !type.equals(getter.getReturnType())) { continue; } if ("parameters".equals(property)) {//有parameters属性,解析元素的全部parameter元素 parameters = parseParameters(element.getChildNodes(), beanDefinition); } else if ("methods".equals(property)) {//有methods属性,就解析配置元素的全部method元素 放到beanDefinition “methods” 配置里 parseMethods(id, element.getChildNodes(), beanDefinition, parserContext); } else if ("arguments".equals(property)) {//有arguments属性,就解析全部的argument元素 parseArguments(id, element.getChildNodes(), beanDefinition, parserContext); } else { String value = element.getAttribute(property); if (value != null) { value = value.trim(); if (value.length() > 0) { if ("registry".equals(property) && RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(value)) { RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress(RegistryConfig.NO_AVAILABLE); beanDefinition.getPropertyValues().addPropertyValue(property, registryConfig); } else if ("registry".equals(property) && value.indexOf(',') != -1) { //解析多个以逗号分割的多个registry配置 放到 beanDefinition registries属性里 parseMultiRef("registries", value, beanDefinition, parserContext); } else if ("provider".equals(property) && value.indexOf(',') != -1) { //解析多个以逗号分割的多个provider配置 放到 beanDefinition providers属性里 parseMultiRef("providers", value, beanDefinition, parserContext); } else if ("protocol".equals(property) && value.indexOf(',') != -1) { //解析多个以逗号分割的多个protocol配置 放到 beanDefinition protocols属性里 parseMultiRef("protocols", value, beanDefinition, parserContext); } else { Object reference; if (isPrimitive(type)) {//set 方法参数是方法指定的原始类型 if ("async".equals(property) && "false".equals(value) || "timeout".equals(property) && "0".equals(value) || "delay".equals(property) && "0".equals(value) || "version".equals(property) && "0.0.0".equals(value) || "stat".equals(property) && "-1".equals(value) || "reliable".equals(property) && "false".equals(value)) { // 兼容旧版本xsd中的default值 value = null; } //直接赋值 reference = value; } else if ("protocol".equals(property) && ExtensionLoader.getExtensionLoader(Protocol.class).hasExtension(value) && (!parserContext.getRegistry().containsBeanDefinition(value) || !ProtocolConfig.class.getName().equals(parserContext.getRegistry().getBeanDefinition(value).getBeanClassName()))) { if ("dubbo:provider".equals(element.getTagName())) { logger.warn("Recommended replace <dubbo:provider protocol=\"" + value + "\" ... /> to <dubbo:protocol name=\"" + value + "\" ... />"); } //兼容旧版本配置 ProtocolConfig protocol = new ProtocolConfig(); protocol.setName(value); reference = protocol; } else if ("monitor".equals(property) && (!parserContext.getRegistry().containsBeanDefinition(value) || !MonitorConfig.class.getName().equals(parserContext.getRegistry().getBeanDefinition(value).getBeanClassName()))) { //兼容旧版本配置 reference = convertMonitor(value); } else if ("onreturn".equals(property)) {//回调函数设置 service.ontrenMethod int index = value.lastIndexOf("."); String returnRef = value.substring(0, index); String returnMethod = value.substring(index + 1); reference = new RuntimeBeanReference(returnRef); beanDefinition.getPropertyValues().addPropertyValue("onreturnMethod", returnMethod); } else if ("onthrow".equals(property)) { int index = value.lastIndexOf("."); String throwRef = value.substring(0, index); String throwMethod = value.substring(index + 1); reference = new RuntimeBeanReference(throwRef); beanDefinition.getPropertyValues().addPropertyValue("onthrowMethod", throwMethod); } else {//解析ref 属性 if ("ref".equals(property) && parserContext.getRegistry().containsBeanDefinition(value)) { BeanDefinition refBean = parserContext.getRegistry().getBeanDefinition(value); if (!refBean.isSingleton()) { throw new IllegalStateException("The exported service ref " + value + " must be singleton! Please set the " + value + " bean scope to singleton, eg: <bean id=\"" + value + "\" scope=\"singleton\" ...>"); } } reference = new RuntimeBeanReference(value); } beanDefinition.getPropertyValues().addPropertyValue(property, reference); } } } } } } //element 自己全部属性 放入beanDefinition的parameters NamedNodeMap attributes = element.getAttributes(); int len = attributes.getLength(); for (int i = 0; i < len; i++) { Node node = attributes.item(i); String name = node.getLocalName(); if (!props.contains(name)) { if (parameters == null) { parameters = new ManagedMap(); } String value = node.getNodeValue(); parameters.put(name, new TypedStringValue(value, String.class)); } } if (parameters != null) { beanDefinition.getPropertyValues().addPropertyValue("parameters", parameters); } return beanDefinition; }
ReferenceBean类主要完成在适当的时机(spring bean初始化完成,或者用户经过spring容器获取bean)
根据服务调用方配置,生成服务调用代理的工做。api
ReferenceBean继承类层:app
能够看到,ReferenceBean及其基类实现了FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean 4个接口的方法,
经过spring回调机制,完成spring容器传入,获取bean类型,bean初始化和destory定制等操做。ReferenceBean类里具体方法实现:async
/*** * 实现ApplicationContextAware接口方法。在bean初始化时,回传bean所在容器的引用 * @param applicationContext */ public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; //容器引用,传入SpringExtensionFactory SpringExtensionFactory.addApplicationContext(applicationContext); } /*** * 实现FactoryBean接口方法, * 返回一个bean实例,在使用spring api 向容器获取一个bean时调用 * 这里返回的是reference代理 * @return * @throws Exception */ public Object getObject() throws Exception { return get(); } /*** * 实现FactoryBean接口方法, * 返回一个bean的类型 * @return */ public Class<?> getObjectType() { return getInterfaceClass(); } /*** * 实现FactoryBean接口方法, * 返回一个bean的是不是单例 * @return */ @Parameter(excluded = true) public boolean isSingleton() { return true; } /*** * 实现InitializingBean接口方法, * 在bean 全部(提供的)属性值都赋值后,由spring回调执行 * 这个方法里能够作些初始化定制 * @throws Exception */ @SuppressWarnings({"unchecked"}) public void afterPropertiesSet() throws Exception { if (getConsumer() == null) { //BeanFactoryUtils.beansOfTypeIncludingAncestors是spring的一个工具类, // 它返回指定容器里,ConsumerConfig.class类及其子类的bean,若是还没初始化,会触发初始化的过程,依赖注入的概念 Map<String, ConsumerConfig> consumerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConsumerConfig.class, false, false); if (consumerConfigMap != null && consumerConfigMap.size() > 0) { ConsumerConfig consumerConfig = null; //遍历map 默认设置ConsumerConfig for (ConsumerConfig config : consumerConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (consumerConfig != null) { throw new IllegalStateException("Duplicate consumer configs: " + consumerConfig + " and " + config); } consumerConfig = config; } } //设置ConsumerConfig if (consumerConfig != null) { setConsumer(consumerConfig); } } } //设置ApplicationConfig if (getApplication() == null && (getConsumer() == null || getConsumer().getApplication() == null)) { Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false); if (applicationConfigMap != null && applicationConfigMap.size() > 0) { ApplicationConfig applicationConfig = null; for (ApplicationConfig config : applicationConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (applicationConfig != null) { throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config); } applicationConfig = config; } } if (applicationConfig != null) { setApplication(applicationConfig); } } } //设置ModuleConfig if (getModule() == null && (getConsumer() == null || getConsumer().getModule() == null)) { Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false); if (moduleConfigMap != null && moduleConfigMap.size() > 0) { ModuleConfig moduleConfig = null; for (ModuleConfig config : moduleConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (moduleConfig != null) { throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config); } moduleConfig = config; } } if (moduleConfig != null) { setModule(moduleConfig); } } } //注册中心能够有多个 if ((getRegistries() == null || getRegistries().size() == 0) && (getConsumer() == null || getConsumer().getRegistries() == null || getConsumer().getRegistries().size() == 0) && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) { //多个注册中心 Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false); if (registryConfigMap != null && registryConfigMap.size() > 0) { List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>(); for (RegistryConfig config : registryConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { registryConfigs.add(config); } } if (registryConfigs != null && registryConfigs.size() > 0) { super.setRegistries(registryConfigs); } } } //设置监控中心 if (getMonitor() == null && (getConsumer() == null || getConsumer().getMonitor() == null) && (getApplication() == null || getApplication().getMonitor() == null)) { Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false); if (monitorConfigMap != null && monitorConfigMap.size() > 0) { MonitorConfig monitorConfig = null; for (MonitorConfig config : monitorConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (monitorConfig != null) { throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config); } monitorConfig = config; } } if (monitorConfig != null) { setMonitor(monitorConfig); } } } //是否bean建立后就初始化代理 Boolean b = isInit(); if (b == null && getConsumer() != null) { b = getConsumer().isInit(); } if (b != null && b.booleanValue()) {//当即初始化代理 getObject(); } }
ServiceBean类主要完成,在适当的时机(spring 容器初始化完成或者服务实例初始化完成)根据服务提供方配置暴露发布服务的工做。ServiceBean类继承层以下:ide
能够看到ServiceBean及其基类实现了InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware接口
经过spring回调机制完成spring容器引用传入,bean初始化和destory过程定制,以及监听并处理spring事件的操做。ServiceBean类具体方法实现:函数
/*** * ApplicationContextAware接口方法, * 传入bean 所在容器引用 * @param applicationContext */ public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; //把spring 容器传入SpringExtensionFactory SpringExtensionFactory.addApplicationContext(applicationContext); //获取容器addApplicationListener方法,把当前类加入到容器监听器队列 if (applicationContext != null) { SPRING_CONTEXT = applicationContext; try { Method method = applicationContext.getClass().getMethod("addApplicationListener", new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1 method.invoke(applicationContext, new Object[]{this}); supportedApplicationListener = true; } catch (Throwable t) { if (applicationContext instanceof AbstractApplicationContext) { try { Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1 if (!method.isAccessible()) { method.setAccessible(true); } method.invoke(applicationContext, new Object[]{this}); supportedApplicationListener = true; } catch (Throwable t2) { } } } } } /*** * BeanNameAware接口方法,设置beanName值 * @param name */ public void setBeanName(String name) { this.beanName = name; } /*** * 实现ApplicationListener接口方法, * 本方法会接受并处理在容器初始化完成时发布的ContextRefreshedEvent事件, * 即容器初始化完成后 暴露服务 * @param event */ public void onApplicationEvent(ApplicationEvent event) { if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) { if (isDelay() && !isExported() && !isUnexported()) { if (logger.isInfoEnabled()) { logger.info("The service ready on spring started. service: " + getInterface()); } //执行暴露过程 export(); } } } /*** * InitializingBean 接口方法,bean 属性初始化后,操做处理 * @throws Exception */ @SuppressWarnings({"unchecked", "deprecation"}) public void afterPropertiesSet() throws Exception { //设置ProviderConfig if (getProvider() == null) { Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false); if (providerConfigMap != null && providerConfigMap.size() > 0) { Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false); if ((protocolConfigMap == null || protocolConfigMap.size() == 0) && providerConfigMap.size() > 1) { // 兼容旧版本 List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>(); for (ProviderConfig config : providerConfigMap.values()) { if (config.isDefault() != null && config.isDefault().booleanValue()) { providerConfigs.add(config); } } if (providerConfigs.size() > 0) { setProviders(providerConfigs); } } else { ProviderConfig providerConfig = null; for (ProviderConfig config : providerConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (providerConfig != null) { throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config); } providerConfig = config; } } if (providerConfig != null) { setProvider(providerConfig); } } } } if (getApplication() == null && (getProvider() == null || getProvider().getApplication() == null)) { Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false); if (applicationConfigMap != null && applicationConfigMap.size() > 0) { ApplicationConfig applicationConfig = null; for (ApplicationConfig config : applicationConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (applicationConfig != null) { throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config); } applicationConfig = config; } } if (applicationConfig != null) { setApplication(applicationConfig); } } } if (getModule() == null && (getProvider() == null || getProvider().getModule() == null)) { Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false); if (moduleConfigMap != null && moduleConfigMap.size() > 0) { ModuleConfig moduleConfig = null; for (ModuleConfig config : moduleConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (moduleConfig != null) { throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config); } moduleConfig = config; } } if (moduleConfig != null) { setModule(moduleConfig); } } } if ((getRegistries() == null || getRegistries().size() == 0) && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0) && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) { Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false); if (registryConfigMap != null && registryConfigMap.size() > 0) { List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>(); for (RegistryConfig config : registryConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { registryConfigs.add(config); } } if (registryConfigs != null && registryConfigs.size() > 0) { super.setRegistries(registryConfigs); } } } if (getMonitor() == null && (getProvider() == null || getProvider().getMonitor() == null) && (getApplication() == null || getApplication().getMonitor() == null)) { Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false); if (monitorConfigMap != null && monitorConfigMap.size() > 0) { MonitorConfig monitorConfig = null; for (MonitorConfig config : monitorConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { if (monitorConfig != null) { throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config); } monitorConfig = config; } } if (monitorConfig != null) { setMonitor(monitorConfig); } } } //服务协议,能够有多个 if ((getProtocols() == null || getProtocols().size() == 0) && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) { Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false); if (protocolConfigMap != null && protocolConfigMap.size() > 0) { List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>(); for (ProtocolConfig config : protocolConfigMap.values()) { if (config.isDefault() == null || config.isDefault().booleanValue()) { protocolConfigs.add(config); } } if (protocolConfigs != null && protocolConfigs.size() > 0) { super.setProtocols(protocolConfigs); } } } //设置服务路径 类全名 if (getPath() == null || getPath().length() == 0) { if (beanName != null && beanName.length() > 0 && getInterface() != null && getInterface().length() > 0 && beanName.startsWith(getInterface())) { setPath(beanName); } } //是否延迟暴露 if (!isDelay()) { export();//暴露服务 } } /*** * DisposableBean接口方法,再单例bean 析构时,回调 * 回收资源,这里调用unexport方法 * @throws Exception */ public void destroy() throws Exception { unexport(); }
这个类使得dubbo具备自动包扫描的功能,支持dubbo经过注解配置service和refernece bean(有些属性不能注解配置),并完成ServiceBean和ReferenceBean相同的功能。类图:工具
能够看到AnnotationBean及其父类实现了接口DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware一样经过spring接口方法回调,实现bean实例的初始化预处理。
AnnotationBean类是基于ClassPathBeanDefinitionScanner类实现的。
自动包扫描先看下
org.springframework.context.annotation.ClassPathBeanDefinitionScanner类,
官方解释:
A bean definition scanner that detects bean candidates on the classpath, registering corresponding bean definitions with a given registry (BeanFactory or ApplicationContext). Candidate classes are detected through configurable type filters. The default filters include classes that are annotated with Spring's @Component, @Repository, @Service, or @Controller stereotype.
说人话,就是ClassPathBeanDefinitionScanner会自动在classpatch里扫描并注册
@Component, @Repository, @Service, or @Controller的beans,至关于自动完成
上面说的DubboBeanDefinitionParser类的相似工做。这个类默认处理上面说的4种注解,
但能经过filter添加新的要扫描处理的注解。主要代码实现:
/*** * 设置要扫描的包名,以逗号分隔多个包名 * @param annotationPackage */ public void setPackage(String annotationPackage) { this.annotationPackage = annotationPackage; this.annotationPackages = (annotationPackage == null || annotationPackage.length() == 0) ? null : Constants.COMMA_SPLIT_PATTERN.split(annotationPackage); } /*** * 实现spring 回调接口方法,传入的容器引用 * @param applicationContext * @throws BeansException */ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /*** * 实现BeanFactoryPostProcessor接口 * 这个方法会在,全部的bean definitions已加载, * 可是还没实例化以前回调执行 * 能够在bean初始化以前定制化一些操做 * 这里作的是,调用org.springframework.context.annotation.ClassPathBeanDefinitionScanner的scan方法, * 扫描并注册有 Service(dubbo定义) 注解的bean * 固然都是用反射完成的 * @param beanFactory * @throws BeansException */ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (annotationPackage == null || annotationPackage.length() == 0) { return; } if (beanFactory instanceof BeanDefinitionRegistry) { try { // init scanner //利用反射构造ClassPathBeanDefinitionScanner实例,用的这个构造方法, // useDefaultFilters=true 默认扫描 spring 4种的注解 // public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { // this(registry, useDefaultFilters, getOrCreateEnvironment(registry)); // } Class<?> scannerClass = ReflectUtils.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner"); Object scanner = scannerClass.getConstructor(new Class<?>[]{BeanDefinitionRegistry.class, boolean.class}).newInstance(new Object[]{(BeanDefinitionRegistry) beanFactory, true}); // add filter //经过filter 添加新要扫描的注解,也是用的反射 这里是 AnnotationTypeFilter Class<?> filterClass = ReflectUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter"); Object filter = filterClass.getConstructor(Class.class).newInstance(Service.class); //获取添加filter的方法,并调用 Method addIncludeFilter = scannerClass.getMethod("addIncludeFilter", ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter")); addIncludeFilter.invoke(scanner, filter); // scan packages //获取 ClassPathBeanDefinitionScanner的 scan(java.lang.String... basePackages) 方法,开始扫描 String[] packages = Constants.COMMA_SPLIT_PATTERN.split(annotationPackage); Method scan = scannerClass.getMethod("scan", new Class<?>[]{String[].class}); scan.invoke(scanner, new Object[]{packages}); } catch (Throwable e) { // spring 2.0 } } } /*** * 实现DisposableBean接口 * 在bean 析构时,调用相关方法,释放资源 * @throws Exception */ public void destroy() throws Exception { for (ServiceConfig<?> serviceConfig : serviceConfigs) { try { serviceConfig.unexport(); } catch (Throwable e) { logger.error(e.getMessage(), e); } } for (ReferenceConfig<?> referenceConfig : referenceConfigs.values()) { try { referenceConfig.destroy(); } catch (Throwable e) { logger.error(e.getMessage(), e); } } } /*** * 实现BeanPostProcessor接口方法 * 在bean初始化后 好比在afterPropertiesSet后由spring回调执行 * 这个方法完成相似ServiceBean的工做 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { //检查是否匹配包名 if (!isMatchPackage(bean)) { return bean; } //手动建立 ServiceBean 并暴露服务 Service service = bean.getClass().getAnnotation(Service.class); if (service != null) { ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service); serviceConfig.setRef(bean); if (void.class.equals(service.interfaceClass()) && "".equals(service.interfaceName())) { if (bean.getClass().getInterfaces().length > 0) { serviceConfig.setInterface(bean.getClass().getInterfaces()[0]); } else { throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces."); } } if (applicationContext != null) { serviceConfig.setApplicationContext(applicationContext); if (service.registry() != null && service.registry().length > 0) { List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>(); for (String registryId : service.registry()) { if (registryId != null && registryId.length() > 0) { registryConfigs.add((RegistryConfig) applicationContext.getBean(registryId, RegistryConfig.class)); } } serviceConfig.setRegistries(registryConfigs); } if (service.provider() != null && service.provider().length() > 0) { serviceConfig.setProvider((ProviderConfig) applicationContext.getBean(service.provider(), ProviderConfig.class)); } if (service.monitor() != null && service.monitor().length() > 0) { serviceConfig.setMonitor((MonitorConfig) applicationContext.getBean(service.monitor(), MonitorConfig.class)); } if (service.application() != null && service.application().length() > 0) { serviceConfig.setApplication((ApplicationConfig) applicationContext.getBean(service.application(), ApplicationConfig.class)); } if (service.module() != null && service.module().length() > 0) { serviceConfig.setModule((ModuleConfig) applicationContext.getBean(service.module(), ModuleConfig.class)); } if (service.provider() != null && service.provider().length() > 0) { serviceConfig.setProvider((ProviderConfig) applicationContext.getBean(service.provider(), ProviderConfig.class)); } else { } if (service.protocol() != null && service.protocol().length > 0) { List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>(); for (String protocolId : service.protocol()) { if (protocolId != null && protocolId.length() > 0) { protocolConfigs.add((ProtocolConfig) applicationContext.getBean(protocolId, ProtocolConfig.class)); } } serviceConfig.setProtocols(protocolConfigs); } try { //调用ServiceBean afterPropertiesSet初始化配置 serviceConfig.afterPropertiesSet(); } catch (RuntimeException e) { throw (RuntimeException) e; } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } } serviceConfigs.add(serviceConfig); //暴露服务 serviceConfig.export(); } return bean; } /*** * /*** * 实现BeanPostProcessor接口方法 * 在bean初始化前 好比在afterPropertiesSet前 由spring 回调执行 * 这个方法完成相似RefercencBean的工做 * @param bean * @param beanName * @return * @throws BeansException */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!isMatchPackage(bean)) { return bean; } //由于dubbo Reference 注解只能在类的字段,或方法上 //经过bean 的set 方法上 找duboo 注解 Method[] methods = bean.getClass().getMethods(); for (Method method : methods) { String name = method.getName(); if (name.length() > 3 && name.startsWith("set") && method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) { try { Reference reference = method.getAnnotation(Reference.class); if (reference != null) { Object value = refer(reference, method.getParameterTypes()[0]); if (value != null) { method.invoke(bean, new Object[]{value}); } } } catch (Throwable e) { logger.error("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e); } } } //经过bean 的字段 上 找duboo 注解 Field[] fields = bean.getClass().getDeclaredFields(); for (Field field : fields) { try { if (!field.isAccessible()) { field.setAccessible(true); } Reference reference = field.getAnnotation(Reference.class); if (reference != null) { Object value = refer(reference, field.getType()); if (value != null) { field.set(bean, value); } } } catch (Throwable e) { logger.error("Failed to init remote service reference at filed " + field.getName() + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e); } } return bean; } /*** * 经过解析 reference注解里的值,去构造服务调用配置,最后调用建立代理的方法 * @param reference * @param referenceClass * @return */ private Object refer(Reference reference, Class<?> referenceClass) { //method.getParameterTypes()[0] String interfaceName; if (!"".equals(reference.interfaceName())) { interfaceName = reference.interfaceName(); } else if (!void.class.equals(reference.interfaceClass())) { interfaceName = reference.interfaceClass().getName(); } else if (referenceClass.isInterface()) { interfaceName = referenceClass.getName(); } else { throw new IllegalStateException("The @Reference undefined interfaceClass or interfaceName, and the property type " + referenceClass.getName() + " is not a interface."); } String key = reference.group() + "/" + interfaceName + ":" + reference.version(); ReferenceBean<?> referenceConfig = referenceConfigs.get(key); if (referenceConfig == null) { referenceConfig = new ReferenceBean<Object>(reference); if (void.class.equals(reference.interfaceClass()) && "".equals(reference.interfaceName()) && referenceClass.isInterface()) { referenceConfig.setInterface(referenceClass); } if (applicationContext != null) { referenceConfig.setApplicationContext(applicationContext); if (reference.registry() != null && reference.registry().length > 0) { List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>(); for (String registryId : reference.registry()) { if (registryId != null && registryId.length() > 0) { registryConfigs.add((RegistryConfig) applicationContext.getBean(registryId, RegistryConfig.class)); } } referenceConfig.setRegistries(registryConfigs); } if (reference.consumer() != null && reference.consumer().length() > 0) { referenceConfig.setConsumer((ConsumerConfig) applicationContext.getBean(reference.consumer(), ConsumerConfig.class)); } if (reference.monitor() != null && reference.monitor().length() > 0) { referenceConfig.setMonitor((MonitorConfig) applicationContext.getBean(reference.monitor(), MonitorConfig.class)); } if (reference.application() != null && reference.application().length() > 0) { referenceConfig.setApplication((ApplicationConfig) applicationContext.getBean(reference.application(), ApplicationConfig.class)); } if (reference.module() != null && reference.module().length() > 0) { referenceConfig.setModule((ModuleConfig) applicationContext.getBean(reference.module(), ModuleConfig.class)); } if (reference.consumer() != null && reference.consumer().length() > 0) { referenceConfig.setConsumer((ConsumerConfig) applicationContext.getBean(reference.consumer(), ConsumerConfig.class)); } try { referenceConfig.afterPropertiesSet(); } catch (RuntimeException e) { throw (RuntimeException) e; } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } } referenceConfigs.putIfAbsent(key, referenceConfig); referenceConfig = referenceConfigs.get(key); } //服务调用的代理建立 return referenceConfig.get(); }