import java.lang.reflect.Method;

public class AppendAnnotation {
/**
* 获取某个Annotation实例的所有方法值(实际是Annotation的属性值),并把这些方法的值赋值给调用此方法的类的相关的setter方法。
*/
protected void appendAnnotation(Class<?> annotationClass, Object annotation) {
Method[] methods = annotationClass.getMethods(); // 从当前类或接口中(包括父类或父接口)获取公开(public)的方法
for (Method method : methods) {
if (method.getDeclaringClass() != Object.class // 方法所在类不是Object本身
&& method.getReturnType() != void.class // 方法的返回类型不是void
&& method.getParameterTypes().length == 0 // 方法的参数个数为0
&& Modifier.isPublic(method.getModifiers()) // 方法的修饰符为public
&& !Modifier.isStatic(method.getModifiers())) // 方法不是静态的
{
try {
String property = method.getName(); // 方法名称 // 如果方法的名称为“interfaceClass”或者interfaceName”,则统一把方法名称:property的值设置为“interface”
if ("interfaceClass".equals(property) || "interfaceName".equals(property)) {
property = "interface";
} // 构造set方法的完整名称,比如:set+V+ersion=setVersion、set+G+roup=setGroup等等
String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1); // 通过反射的方式来调用底层方法,annotaion为被调用方法所在的对象(这里是Annotaion对象),value为方法返回值,实际上就是我们设置的annotaion的属性值。
Object value = method.invoke(annotation); // 如果属性值不为null并且不是方法返回值的默认值
if (value != null && !value.equals(method.getDefaultValue())) { // 把方法返回值的类型进行装箱
Class<?> parameterType = ReflectUtils.getBoxedClass(method.getReturnType()); // 如果方法名称(属性名称)为filter或listner,annotation中filter和listner定义的是string[]类型
if ("filter".equals(property) || "listener".equals(property)) {
parameterType = String.class;
value = StringUtils.join((String[]) value, ",");
} else if ("parameters".equals(property)) { // String[] parameters() default
// {};这种情况下把string[]转换为Map
parameterType = Map.class;
value = CollectionUtils.toStringMap((String[]) value);
}
try {
// 获取AppendAnnotation方法所在类的setter名称所对应的方法(比如:ReferenceConfig类型的setConnections方法,参数值类型为:Integer)
Method setterMethod = getClass().getMethod(setter, parameterType); // 通过反射的方式来调用setter方法(相当于new ReferenceConfig().setConnections(1)这样)
setterMethod.invoke(this, value);
} catch (NoSuchMethodException e) {
// ignore
}
}
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
}
}
}

Dubbo源码解读:appendAnnotation [01]的更多相关文章

  1. Dubbo源码解读

    1.提升SOA的微服务架构设计能力   通过读dubbo源码是一条非常不错的通往SOA架构设计之路,毕竟SOA的服务治理就是dubbo首先提出来的,比起你去看市面上的SOA微服务架构的书籍,学到的架构 ...

  2. prototype.js 源码解读(01)

    prototype.js是一个设计的非常优雅且很有实用价值的js基础类库,其源码非常值得研究.研究它的源码不仅能提升个人水平,而且对你打下坚实的js基础也很有帮助.因本人技术水平有限,该解读仅供参考. ...

  3. 【Dubbo 源码解析】07_Dubbo 重试机制

    Dubbo 重试机制 通过前面 Dubbo 服务发现&引用 的分析,我们知道,Dubbo 的重试机制是通过 com.alibaba.dubbo.rpc.cluster.support.Fail ...

  4. 【Dubbo 源码解析】06_Dubbo 服务调用

    Dubbo 服务调用 根据上图,可以看出,服务调用过程为: Consumer 端的 Proxy 调用 Cluster 层选择集群中的某一个 Invoker(负载均衡) Invoker 最终会调用 Pr ...

  5. 【Dubbo 源码解析】05_Dubbo 服务发现&引用

    Dubbo 服务发现&引用 Dubbo 引用的服务消费者最终会构造成一个 Spring 的 Bean,具体是通过 ReferenceBean 来实现的.它是一个 FactoryBean,所有的 ...

  6. 【Dubbo 源码解析】04_Dubbo 服务注册&暴露

    Dubbo 服务注册&暴露 Dubbo 服务暴露过程是通过 com.alibaba.dubbo.config.spring.ServiceBean 来实现的.Spring 容器 refresh ...

  7. 【Dubbo 源码解析】03_Dubbo Protocol&Filter

    Protocol & Filter Dubbo 服务暴露和服务引用都是通过的 com.alibaba.dubbo.rpc.Protocol 来实现的.它是一个 SPI 扩展. @SPI(&qu ...

  8. 【Dubbo 源码解析】02_Dubbo SPI

    Dubbo SPI:(version:2.6.*) Dubbo 微内核 + 插件 模式,得益于 Dubbo SPI .其中 ExtentionLoader是 Dubbo SPI 最核心的类,它负责扩展 ...

  9. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

随机推荐

  1. Android Activity启动流程源码全解析(2)

    接上之前的分析 ++Android Activity启动流程源码全解析(1)++ 1.正在运行的Activity调用startPausingLocked 一个一个分析,先来看看startPausing ...

  2. Kubeadm安装Kubernetes环境

    Kubeadm方式号称一键安装部署,很多人也试过并且顺利成功,可到了我这里因为折腾系统问题,倒腾出不少的坑出来. kubeadm好处是自动配置了必要的服务,以及缺省配置了安全的认证,etcd,apis ...

  3. 在 JDK 9 中更简洁使用 try-with-resources 语句

    本文详细介绍了自 JDK 7 引入的 try-with-resources 语句的原理和用法,以及介绍了 JDK 9 对 try-with-resources 的改进,使得用户可以更加方便.简洁的使用 ...

  4. 深入探索 JUnit 4

    开始之前 关于本教程 引入 Java 5 注释为 JUnit 带来了显著改变,使它从一个受广大开发人员了解和喜爱的测试框架转变成了一个更为精简但却不那么为人熟知的框架.在本教程中,我将探讨 JUnit ...

  5. 使用Idea创建多Module工程

    1. 点击 New -- Project 2. 设置工程父Pom, 如下 <?xml version="1.0" encoding="UTF-8"?> ...

  6. 检测Sql Server服务器SQL语句执行情况

    1.查找目前SQL Server所执行的SQL语法,并展示资源情况: SQL code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ...

  7. C/C++ 分支预测(likely unlikely)

    看一些代码时,会遇到likely unlikely, 查了查网上的资料,结合自己的理解记录一下. 1. 一些概念 指令周期是指执行一条指令所需要的时间,一般由若干个机器周期组成,是从取指令.分析指令到 ...

  8. 在EntityFramework6中执行SQL语句【转】

    在上一节中我介绍了如何使用EF6对数据库实现CRDU以及事务,我们没有写一句SQL就完成了所有操作.这一节我来介绍一下如何使用在EF6中执行SQL语句. 你可能要问,我用EF不就为了避免写SQL吗?如 ...

  9. 初识EntityFramework6【转】

    http://www.cnblogs.com/wujingtao/p/5401132.html 什么是EF? EF是一种ORM(Object-relational mapping)框架,它能把我们在编 ...

  10. Unicode与JavaScript详解 [很好的文章转]

    上个月,我做了一次分享,详细介绍了Unicode字符集,以及JavaScript语言对它的支持.下面就是这次分享的讲稿. 一.Unicode是什么? Unicode源于一个很简单的想法:将全世界所有的 ...