Dubbo源码分析之二:spring集成之注解

dubbo的注解配置主要是com.alibaba.dubbo.config.spring.AnnotationBean

该类实现了DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware 接口

重点在BeanFactoryPostProcessor 和 BeanPostProcessor。其中BeanFactoryPostProcessor是可以修改Bean的。


public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) // 实现BeanFactoryPostProcessor
            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
            }
        }
    }

然后看看BeanPostProcessor接口中的方法

public Object postProcessBeforeInitialization(Object bean, String beanName) //初始化前处理
            throws BeansException {
        if (! isMatchPackage(bean)) {
            return bean;
        }
        Class clazz = bean.getClass();
        if(isProxyBean(bean)){
            clazz = AopUtils.getTargetClass(bean); // 如果是代理则直接返回目标类
        }
        Method[] methods = clazz.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); // 获取setter方法上的reference注解
                	if (reference != null) {
	                 	Object value = refer(reference, method.getParameterTypes()[0]);//获取对象引用
	                	if (value != null) {
	                 		method.invoke(bean, new Object[] { value }); //setting
	                	}
                	}
                } catch (Exception e) {
                    // modified by lishen
                    throw new BeanInitializationException("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName(), e);
//                    logger.error("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e);
                }
            }
        }
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            try {
                if (! field.isAccessible()) {
                    field.setAccessible(true);
                }
                Reference reference = field.getAnnotation(Reference.class); // 获取字段上的reference注解
            	if (reference != null) {
	                Object value = refer(reference, field.getType());
	                if (value != null) {
	                	field.set(bean, value); //设置
	                }
            	}
            } catch (Exception e) {
                // modified by lishen
                throw new BeanInitializationException("Failed to init remote service reference at filed " + field.getName() + " in class " + bean.getClass().getName(), e);
//            	logger.error("Failed to init remote service reference at filed " + field.getName() + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e);
            }
        }
        return bean;
    }

public Object postProcessAfterInitialization(Object bean, String beanName) // 初始化后处理,主要是暴露服务
            throws BeansException {
        if (! isMatchPackage(bean)) {
            return bean;
        }
        Class clazz = bean.getClass();
        if(isProxyBean(bean)){
            clazz = AopUtils.getTargetClass(bean); //获取目标类
        }
        Service service = clazz.getAnnotation(Service.class); // 获取class上的Service注解
        if (service != null) {
            ServiceBean serviceConfig = new ServiceBean(service); //初始化一个服务
            if (void.class.equals(service.interfaceClass())
                    && "".equals(service.interfaceName())) {
                if (clazz.getInterfaces().length > 0) {
                    serviceConfig.setInterface(clazz.getInterfaces()[0]); // 服务对应的接口
                } else {
                    throw new IllegalStateException("Failed to export remote service class " + clazz.getName() + ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces.");
                }
            }
            
             // 从spring中获取服务需要的相关属性
            if (applicationContext != null) {
                serviceConfig.setApplicationContext(applicationContext);
                if (service.registry() != null && service.registry().length > 0) {
                    List registryConfigs = new ArrayList();
                    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 protocolConfigs = new ArrayList();
                    // modified by lishen; fix dubbo's bug
                    for (String protocolId : service.protocol()) {
                        if (protocolId != null && protocolId.length() > 0) {
                            protocolConfigs.add((ProtocolConfig)applicationContext.getBean(protocolId, ProtocolConfig.class));
                        }
                    }
                    serviceConfig.setProtocols(protocolConfigs);
                }
                try {
                     // 设置一些配置信息,如:applicationConfig,protocolConfigs,与上面类似
                     // 最后 如果不延迟就导出
                    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;
}




 
  

 
  
注解只针对Service Reference。

你可能感兴趣的:(Dubbo源码分析)