【Pigeon源码阅读】整合Spring注解解析原理(三)

本文详细解析了Pigeon如何整合Spring注解,包括Pigeon的使用方法,注解解析器的注册,XML配置的注解标签解析,以及@Service和@Reference注解的扫描和依赖注入原理。
摘要由CSDN通过智能技术生成

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会注册当前注解解析器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值