文章目录
pigeon使用方法
pigeon通过配置<pigeon:annotation package="com.dianping.pigeon.demo.annotation"/>
实现注解扫描配置的方式,其中package属性是具体扫描的包,默认扫描com.dianping下所有包。
在Pigeon中主要使用了@Reference和@Service注解,用来标志服务调用方接口和服务提供方实现类,内部定义的配置分别和InvokerConfig和ProviderConfig相对应,具体定义如下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE})
public @interface Service {
// 服务接口名
Class<?> interfaceClass() default void.class;
// 服务url
String url() default "";
// 服务版本
String version() default "";
// 服务分组,即泳道,不同泳道访问相互隔离
String group() default "";
// 服务监听端口
int port() default 4040;
// 是否自动选择端口
boolean autoSelectPort() default true;
// 是否为每个服务配置独立的线程池
boolean useSharedPool() default true;
// 方法级别最大并发数
int actives() default 0;
String token() default "";
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.FIELD, ElementType.METHOD})
public @interface Reference {
// 服务调用接口类
Class<?> interfaceClass() default void.class;
// 访问虚拟ip
String vip() default "";
// 访问url
String url() default "";
// 访问协议
String protocol() default "default";
// 序列化方式
String serialize() default "hessian";
// 调用方式
String callType() default "sync";
// 调用超时时间
int timeout() default 1000;
// 调用回调方法
String callback() default "";
// 负载均衡策略
String loadbalance() default "weightedAutoaware";
// 集群访问策略
String cluster() default "failfast";
// 失败重试次数
int retries() default 1;
// 是否重试超时
boolean timeoutRetry() default false;
// 服务版本
String version() default "";
// 服务分组,即泳道,不同泳道访问相互隔离
String group() default "";
// 访问密钥
String secret() default "";
}
具体使用时,对于服务提供方,只需要实现特定接口,然后在实现类上标注@Service标签,对于服务调用方,只需要在field或method上加上@Reference,具体示例如下:
// EchoService是一个远程服务的接口:
public interface EchoService {
String echo(String input);
}
// 在服务端需要实现这个服务接口,服务实现类上需要加上@Service(com.dianping.pigeon.remoting.provider.config.annotation.Service):
@Service
public class EchoServiceAnnotationImpl implements EchoService {
@Override
public String echo(String input) {
return "annotation service echo:" + input;
}
}
// 假设在客户端有一个AnnotationTestService,需要引用远程的EchoService服务,只需要在field或method上加上@Reference:
public class AnnotationTestService {
@Reference(timeout = 1000)
private EchoService echoService;
public String testEcho(String input) {
return echoService.echo(input);
}
}
pigeon注解解析器注册
在Spring加载BeanDefinition时,识别到xml配置了pigeon命名空间,会根据META-INF/spring.handlers文件下配置的http\://code.dianping.com/schema/pigeon=com.dianping.pigeon.config.spring.CommonNamespaceHandler
找到CommonNamespaceHandler,并调用CommonNamespaceHandler#init方法:
public void init() {
// 加载类路径 META-INF.services目录下的com.dianping.pigeon.config.spring.BeanDefinitionParserLoader文件中定义的所有loader
List<BeanDefinitionParserLoader> loaders = ExtensionLoader.getExtensionList(BeanDefinitionParserLoader.class);
if (loaders != null) {
for (BeanDefinitionParserLoader loader : loaders) {
// 调用每个loader的loadBeanDefinitionParsers方法获取每个loader负责的解析器
Map<String, BeanDefinitionParser> parsers = loader.loadBeanDefinitionParsers();
if (parsers != null) {
for (String key : parsers.keySet()) {
// 将解析器注册到BeanDefinitionParser中,在调用parse函数中,根据标签找到相应的解析器进行解析元素
registerBeanDefinitionParser(key, parsers.get(key));
}
}
}
}
}
其中包含初始化AnnotationBeanDefinitionParserLoader,在调用AnnotationBeanDefinitionParserLoader#loadBeanDefinitionParsers时,会初始化AnnotationBeanDefinitionParser,然后调用CommonNamespaceHandler#registerBeanDefinitionParser会注册当前注解解析器