Dubbo注册dubbo服务的源码分析

来源:互联网 发布:钱箱测试软件 编辑:程序博客网 时间:2024/04/30 13:21

在写代码之前先看一下dubbo的源码

Dubbo的基本用法可以查看我的博客
http://www.qbmmj.com/tag/dubbo/

dubbo可以通过xml的方式或者注解的方式来配置注册到注册中心的服务

下边先看看一xml的方式是怎么工作的,在dubbo的源码包目录下我们可以发现两个spring的文件,如下图↓
这里写图片描述
让我们再看看最看是使用xml配置是的配置文件的头部部分,如下图↓
这里写图片描述
当加载到这个配置文件的时候,就会加载到dubbo,再让我们看看spring.handlers这个文件,下边是他的代码↓

http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

让我们看看这个类,下边是源码↓

/* * Copyright 1999-2011 Alibaba Group. *   * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *   *      http://www.apache.org/licenses/LICENSE-2.0 *   * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.alibaba.dubbo.config.spring.schema;import org.springframework.beans.factory.xml.NamespaceHandlerSupport;import com.alibaba.dubbo.common.Version;import com.alibaba.dubbo.config.ApplicationConfig;import com.alibaba.dubbo.config.ConsumerConfig;import com.alibaba.dubbo.config.ModuleConfig;import com.alibaba.dubbo.config.MonitorConfig;import com.alibaba.dubbo.config.ProtocolConfig;import com.alibaba.dubbo.config.ProviderConfig;import com.alibaba.dubbo.config.RegistryConfig;import com.alibaba.dubbo.config.spring.AnnotationBean;import com.alibaba.dubbo.config.spring.ReferenceBean;import com.alibaba.dubbo.config.spring.ServiceBean;/** * DubboNamespaceHandler *  * @author william.liangf * @export */public class DubboNamespaceHandler extends NamespaceHandlerSupport {    static {        Version.checkDuplicate(DubboNamespaceHandler.class);    }    public void init() {        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));    }}

这个类继承了NamespaceHandlerSupport他有个顶级接口NamespaceHandler,parsedecorate方法在NamespaceHandlerSupport中已有实现,这时候DubboNamespaceHandler实现了init方法,并做了一个版本号的容错的检查,是一个静态块。这个类的目的是解析dubbo的标签,当spring容器在启动时会掉用到DubboNamespaceHandler中的init方法,通过查看源码阔以发现对标签中的bean的处理是通过DubboBeanDefinitionParser来处理的,这个类实现了BeanDefinitionParser接口重写了pase方法在pase中调用了一个静态的pase方法去做处理。通过在构造中传入不同的参数来解析不同的Dubbo标签。
到此为止将xml转换为spring的bean定义的操作已经结束了。下边再看看比较核心的serviceBean的创建↓

先看看ServiceBean的源码,下边贴出源码↓

/* * Copyright 1999-2011 Alibaba Group. *   * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *   *      http://www.apache.org/licenses/LICENSE-2.0 *   * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.alibaba.dubbo.config.spring;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import java.util.Map;import org.springframework.beans.factory.BeanFactoryUtils;import org.springframework.beans.factory.BeanNameAware;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;import org.springframework.context.event.ContextRefreshedEvent;import org.springframework.context.support.AbstractApplicationContext;import com.alibaba.dubbo.config.ApplicationConfig;import com.alibaba.dubbo.config.ModuleConfig;import com.alibaba.dubbo.config.MonitorConfig;import com.alibaba.dubbo.config.ProtocolConfig;import com.alibaba.dubbo.config.ProviderConfig;import com.alibaba.dubbo.config.RegistryConfig;import com.alibaba.dubbo.config.ServiceConfig;import com.alibaba.dubbo.config.annotation.Service;import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory;/** * ServiceFactoryBean *  * @author william.liangf * @export */public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware {    private static final long serialVersionUID = 213195494150089726L;    private static transient ApplicationContext SPRING_CONTEXT;    private transient ApplicationContext applicationContext;    private transient String beanName;    private transient boolean supportedApplicationListener;    public ServiceBean() {        super();    }    public ServiceBean(Service service) {        super(service);    }    public static ApplicationContext getSpringContext() {        return SPRING_CONTEXT;    }    public void setApplicationContext(ApplicationContext applicationContext) {        this.applicationContext = applicationContext;        SpringExtensionFactory.addApplicationContext(applicationContext);        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) {                    }                }            }        }    }    public void setBeanName(String name) {        this.beanName = name;    }    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();            }        }    }    private boolean isDelay() {        Integer delay = getDelay();        ProviderConfig provider = getProvider();        if (delay == null && provider != null) {            delay = provider.getDelay();        }        return supportedApplicationListener && (delay == null || delay.intValue() == -1);    }    @SuppressWarnings({ "unchecked", "deprecation" })    public void afterPropertiesSet() throws Exception {        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();        }    }    public void destroy() throws Exception {        unexport();    }}

通过源码阔以发现这个类继承了ServiceConfig实现了五个接口,分别是InitializingBean,DisposableBean,ApplicationContextAware,ApplicationListener,BeanNameAware,下边分析

1.首先是InitializingBean,DisposableBean

Springbean的创建和销毁大概有三种方式:①一种是通过注解指定@PostConstruct 和 @PreDestroy 方法②如果是xml则可以指定init-methoddestory-method③则是通过实现两个接口来实现InitializingBean,DisposableBean

2.ApplicationContextAware

通过这个接口我们可以拿到spring的上下文

3.ApplicationListener
这个借口的作用是可以监听到所用通过applicationContext.publistEvent(ApplicationEvent event))发布的事件,在spring启动时bean初始化完成时会调用publistEvent发布时间,只要是实现了ApplicationListener接口的类都可以接收到时间并作出响应。查看源码阔以发现这里监听的是ContextRefreshedEvent,下边是代码↓

 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();            }        }    }

4.BeanNameAware

通过这个Bean可以获取到自己在容器中的名字

通过上边分析我们看看源码实现

public void setApplicationContext(ApplicationContext applicationContext) {        this.applicationContext = applicationContext;        SpringExtensionFactory.addApplicationContext(applicationContext);        if (applicationContext != null) {            SPRING_CONTEXT = applicationContext;            try {                    //获取容器的`addApplicationListener`方法                Method method = applicationContext.getClass().getMethod("addApplicationListener", new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1                    //通过反射调用`addApplicationListener`是当前类监听当前类的创建完成后的事件                method.invoke(applicationContext, new Object[] {this});                    //将支持容器监听属性设置为true                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) {                    }                }            }        }    }

接到事件后的处理

public void onApplicationEvent(ApplicationEvent event) {        //判断是不是ContextRefreshedEvent        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();            }        }    }

再看看afterPropertiesSet这个函数的操作,这个函数的大致意思是当所有的属性都设置到后,做一些属性的校验,校验完了后,就暴露服务

关于停止暴露服务就很简单了,这里直接调用了父类的unexport方法。

上边是xml的服务注册,下边在看看注解的方式是怎么实现的,在配置配置文件的时候(或者java代码的方式),我们在容器中实例化了一个bean,这个bean是AnnotationBean,这个类在com.alibaba.dubbo.config.spring.AnnotationBean,下边贴出他的代码已做备注

/* * Copyright 1999-2012 Alibaba Group. *   * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *   *      http://www.apache.org/licenses/LICENSE-2.0 *   * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.alibaba.dubbo.config.spring;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.util.ArrayList;import java.util.List;import java.util.Set;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import org.springframework.beans.BeansException;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.BeanPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import com.alibaba.dubbo.common.Constants;import com.alibaba.dubbo.common.logger.Logger;import com.alibaba.dubbo.common.logger.LoggerFactory;import com.alibaba.dubbo.common.utils.ConcurrentHashSet;import com.alibaba.dubbo.common.utils.ReflectUtils;import com.alibaba.dubbo.config.AbstractConfig;import com.alibaba.dubbo.config.ApplicationConfig;import com.alibaba.dubbo.config.ConsumerConfig;import com.alibaba.dubbo.config.ModuleConfig;import com.alibaba.dubbo.config.MonitorConfig;import com.alibaba.dubbo.config.ProtocolConfig;import com.alibaba.dubbo.config.ProviderConfig;import com.alibaba.dubbo.config.ReferenceConfig;import com.alibaba.dubbo.config.RegistryConfig;import com.alibaba.dubbo.config.ServiceConfig;import com.alibaba.dubbo.config.annotation.Reference;import com.alibaba.dubbo.config.annotation.Service;/** * AnnotationBean *  * @author william.liangf * @export */public class AnnotationBean extends AbstractConfig implements DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {    private static final long serialVersionUID = -7582802454287589552L;    private static final Logger logger = LoggerFactory.getLogger(Logger.class);    private String annotationPackage;    private String[] annotationPackages;    private final Set<ServiceConfig<?>> serviceConfigs = new ConcurrentHashSet<ServiceConfig<?>>();    private final ConcurrentMap<String, ReferenceBean<?>> referenceConfigs = new ConcurrentHashMap<String, ReferenceBean<?>>();    public String getPackage() {        return annotationPackage;    }    public void setPackage(String annotationPackage) {        this.annotationPackage = annotationPackage;        this.annotationPackages = (annotationPackage == null || annotationPackage.length() == 0) ? null                : Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);    }    private ApplicationContext applicationContext;    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        this.applicationContext = applicationContext;    }    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)            throws BeansException {        if (annotationPackage == null || annotationPackage.length() == 0) {            return;        }        if (beanFactory instanceof BeanDefinitionRegistry) {            try {                // init scanner                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                Class<?> filterClass = ReflectUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter");                Object filter = filterClass.getConstructor(Class.class).newInstance(Service.class);                Method addIncludeFilter = scannerClass.getMethod("addIncludeFilter", ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter"));                addIncludeFilter.invoke(scanner, filter);                // scan packages                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            }        }    }    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);            }        }    }    public Object postProcessAfterInitialization(Object bean, String beanName)            throws BeansException {        if (! isMatchPackage(bean)) {            return bean;        }        Service service = bean.getClass().getAnnotation(Service.class);        if (service != null) {            ServiceBean<Object> serviceConfig = new ServiceBean<Object>(service);            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.registry()) {                        if (protocolId != null && protocolId.length() > 0) {                            protocolConfigs.add((ProtocolConfig)applicationContext.getBean(protocolId, ProtocolConfig.class));                        }                    }                    serviceConfig.setProtocols(protocolConfigs);                }                try {                    serviceConfig.afterPropertiesSet();                } catch (RuntimeException e) {                    throw (RuntimeException) e;                } catch (Exception e) {                    throw new IllegalStateException(e.getMessage(), e);                }            }            serviceConfig.setRef(bean);            serviceConfigs.add(serviceConfig);            serviceConfig.export();        }        return bean;    }    public Object postProcessBeforeInitialization(Object bean, String beanName)            throws BeansException {        if (! isMatchPackage(bean)) {            return bean;        }        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[] {  });                        }                    }                } catch (Throwable e) {                    logger.error("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e);                }            }        }        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;    }    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();    }    private boolean isMatchPackage(Object bean) {        if (annotationPackages == null || annotationPackages.length == 0) {            return true;        }        String beanClassName = bean.getClass().getName();        for (String pkg : annotationPackages) {            if (beanClassName.startsWith(pkg)) {                return true;            }        }        return false;    }}

从代码上看出这个类继承了AbstractConfig,实现了四个接口DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware,下边分析下流程

BeanFactoryPostProcessor是容器后置处理器,spring容器在启动时会调用到这个接口中的postProcessBeanFactory实现

BeanPostProcessor是bean后置处理器,这个接口有两个函数需要实现postProcessBeforeInitialization初始化之前postProcessAfterInitialization初始化之后。在初始化bean的时候会调用到这两个函数的实现。

下边先看看postProcessBeanFactory这个函数会在postProcessBeforeInitialization之前调用,他的作用很简单,就是找到dubbo的bean,下边看看代码↓

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {        //判断package是否有效        if(this.annotationPackage != null && this.annotationPackage.length() != 0) {            if(beanFactory instanceof BeanDefinitionRegistry) {                try {                    //加载spring的ClassPathBeanDefinitionScanner类                    Class<?> scannerClass = ReflectUtils.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner");                    //实例化ClassPathBeanDefinitionScanner,将beanFactory作为构造参数传入                    Object scanner = scannerClass.getConstructor(new Class[]{BeanDefinitionRegistry.class, Boolean.TYPE}).newInstance(new Object[]{(BeanDefinitionRegistry)beanFactory, Boolean.valueOf(true)});                    //加载一个过滤器,只扫描dubbo的service注解                    Class<?> filterClass = ReflectUtils.forName("org.springframework.core.type.filter.AnnotationTypeFilter");                    Object filter = filterClass.getConstructor(new Class[]{Class.class}).newInstance(new Object[]{Service.class});                    //将这个过滤器添加到上边的扫描器中,扫描过滤                    Method addIncludeFilter = scannerClass.getMethod("addIncludeFilter", new Class[]{ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter")});                    addIncludeFilter.invoke(scanner, new Object[]{filter});                    //处理用户设置的扫描的包目录                    String[] packages = Constants.COMMA_SPLIT_PATTERN.split(this.annotationPackage);                    //获取扫描器的scan函数                    Method scan = scannerClass.getMethod("scan", new Class[]{String[].class});                    //反射调用开始扫描beanDefinition到beanFactory                    scan.invoke(scanner, new Object[]{packages});                } catch (Throwable var9) {                    ;                }            }        }    }

这个函数的主要作用就是找到dubboServiceBean定义,注册到beanFactory

然后再看看bean的创建部分,postProcessBeforeInitialization函数的工作

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        if(!this.isMatchPackage(bean)) {            return bean;        } else {            Method[] methods = bean.getClass().getMethods();            Method[] arr$ = methods;            int len$ = methods.length;            int len$;            Reference reference;            Object value;            for(len$ = 0; len$ < len$; ++len$) {                Method method = arr$[len$];                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) {                            value = this.refer(reference, method.getParameterTypes()[0]);                            if(value != null) {                                method.invoke(bean, new Object[0]);                            }                        }                    } catch (Throwable var12) {                        logger.error("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + var12.getMessage(), var12);                    }                }            }            Field[] fields = bean.getClass().getDeclaredFields();            Field[] arr$ = fields;            len$ = fields.length;            for(int i$ = 0; i$ < len$; ++i$) {                Field field = arr$[i$];                try {                    if(!field.isAccessible()) {                        field.setAccessible(true);                    }                    reference = (Reference)field.getAnnotation(Reference.class);                    if(reference != null) {                        value = this.refer(reference, field.getType());                        if(value != null) {                            field.set(bean, value);                        }                    }                } catch (Throwable var11) {                    logger.error("Failed to init remote service reference at filed " + field.getName() + " in class " + bean.getClass().getName() + ", cause: " + var11.getMessage(), var11);                }            }            return bean;        }    }

这个方法做的很简单,就是通过set方法来给属性赋值,返回赋值完后的bean。

下边看看postProcessAfterInitialization代码

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {        if(!this.isMatchPackage(bean)) {            return bean;        } else {            Service service = (Service)bean.getClass().getAnnotation(Service.class);            if(service != null) {                ServiceBean<Object> serviceConfig = new ServiceBean(service);                if(Void.TYPE.equals(service.interfaceClass()) && "".equals(service.interfaceName())) {                    if(bean.getClass().getInterfaces().length <= 0) {                        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.");                    }                    serviceConfig.setInterface(bean.getClass().getInterfaces()[0]);                }                if(this.applicationContext != null) {                    serviceConfig.setApplicationContext(this.applicationContext);                    ArrayList protocolConfigs;                    String[] arr$;                    int len$;                    int i$;                    String protocolId;                    if(service.registry() != null && service.registry().length > 0) {                        protocolConfigs = new ArrayList();                        arr$ = service.registry();                        len$ = arr$.length;                        for(i$ = 0; i$ < len$; ++i$) {                            protocolId = arr$[i$];                            if(protocolId != null && protocolId.length() > 0) {                                protocolConfigs.add((RegistryConfig)this.applicationContext.getBean(protocolId, RegistryConfig.class));                            }                        }                        serviceConfig.setRegistries(protocolConfigs);                    }                    if(service.provider() != null && service.provider().length() > 0) {                        serviceConfig.setProvider((ProviderConfig)this.applicationContext.getBean(service.provider(), ProviderConfig.class));                    }                    if(service.monitor() != null && service.monitor().length() > 0) {                        serviceConfig.setMonitor((MonitorConfig)this.applicationContext.getBean(service.monitor(), MonitorConfig.class));                    }                    if(service.application() != null && service.application().length() > 0) {                        serviceConfig.setApplication((ApplicationConfig)this.applicationContext.getBean(service.application(), ApplicationConfig.class));                    }                    if(service.module() != null && service.module().length() > 0) {                        serviceConfig.setModule((ModuleConfig)this.applicationContext.getBean(service.module(), ModuleConfig.class));                    }                    if(service.provider() != null && service.provider().length() > 0) {                        serviceConfig.setProvider((ProviderConfig)this.applicationContext.getBean(service.provider(), ProviderConfig.class));                    }                    if(service.protocol() != null && service.protocol().length > 0) {                        protocolConfigs = new ArrayList();                        arr$ = service.registry();                        len$ = arr$.length;                        for(i$ = 0; i$ < len$; ++i$) {                            protocolId = arr$[i$];                            if(protocolId != null && protocolId.length() > 0) {                                protocolConfigs.add((ProtocolConfig)this.applicationContext.getBean(protocolId, ProtocolConfig.class));                            }                        }                        serviceConfig.setProtocols(protocolConfigs);                    }                    try {                        serviceConfig.afterPropertiesSet();                    } catch (RuntimeException var10) {                        throw var10;                    } catch (Exception var11) {                        throw new IllegalStateException(var11.getMessage(), var11);                    }                }                serviceConfig.setRef(bean);                this.serviceConfigs.add(serviceConfig);                serviceConfig.export();            }            return bean;        }    }

有代码看出这个函数在做的事是校验属性,设置ref添加serviceConfig到serviceConfigs,正确无误后调用export到注册中心的操作。

到此为止,代码分析完毕!
http://www.qbmmj.com/2017/07/21/dubbode-fu-wu-zhu-ce-yan-jiu/

原创粉丝点击