Dubbo源码分析之二:spring集成之注解
2016-05-12 10:48
796 查看
dubbo的注解配置主要是com.alibaba.dubbo.config.spring.AnnotationBean
该类实现了DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware 接口
重点在BeanFactoryPostProcessor 和 BeanPostProcessor。其中BeanFactoryPostProcessor是可以修改Bean的。
然后看看BeanPostProcessor接口中的方法
注解只针对Service Reference。
该类实现了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<Object> serviceConfig = new ServiceBean<Object>(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<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>(); // 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。
相关文章推荐
- Java中关于Null的9个解释(Java Null详解)
- Java之Clone()
- 找到最耗CPU的java线程
- JAVA并发实现五(生产者和消费者模式Condition方式实现)
- 用java实现二叉树相关操作(前序建树,前中后递归非递归遍历,层序遍历)
- 堆排序
- java去空格
- Java正则表达式匹配URL中的host
- java生成订单编号工具
- Spring (依赖注入)
- Java知识图谱收集整理(学习路线等问题)
- java集合学习
- Spring (依赖注入)
- 用Editplus配置JAVA编辑环境
- Fragment之java.lang.IllegalArgumentException: No view found for id异常
- JAVA校验特殊字符
- 【编程语言】Java 软件工程师的一天
- spring cloud stream使用指南
- URL和URI的联系与区别
- 百分百安装成功genymotion教程 eclipse插件 genymotion错误解决