使用注解的方式来自动注册服务

在实现的RPC框架中,如果使用传统的方式来进行通信的话,那么服务启动端需要先手动创建一个提供服务的类的实例

HelloService helloService = new HelloServiceImpl();

虽然在实现过程中只有这一个服务,好像并不会带来太大的问题,但如果有一堆服务对象的话,那有几个就得手动创建几个,这样肯定是不现实的,所以给框架加一个自动注册服务的方式是很有必要的。采用注解的方式来解决这个问题则是个很好的选择。

服务端肯定要有一个注解,当我们启动服务端后,原本是创建一个服务类的实例,需要将这一步省去,这个注解可以视为扫描注解,实现了这个注解之后,我们就知道了在这个位置需要进行扫描。同时,提供服务的类也可以有一个注解,表明它提供了一个服务。

我们就可以设计如下的流程:获取服务启动端所在的类名→判断该类下有无扫描注解→获取注解的值如果值与我们定义的相同,说明是我们需要操作的类→获取它所在的包的名称→扫描包下所有类,逐个判断是否有服务注解→获取注解类实现的接口→得到接口信息,注册服务

//服务注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Service {
    public String name() default "";
}
//扫描注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ServiceScan {

    public String value() default "";
}

服务端

@ServiceScan
public class NettyServerTest {
    public static void main(String[] args) {
        NettyServer server = new NettyServer("127.0.0.1", 9999, CommonSerializer.KRYO_SERIALIZER);
        server.start();
    }
}

这又会出现一个问题,我们知道在服务端启动时需要进行扫描,但是怎么获得这个服务端的类名呢?
我们是通过调用main方法来启动服务的,当一个方法被调用时,实际上是线程调用了它私有的虚拟机栈,将方法作为一个栈帧将其压入虚拟机栈中,一个方法从开始执行到执行完毕对应的就是它的入栈和出栈过程,所以main方法肯定是在栈底的,我们可以通过new Throwable().getStackTrace()方法得到栈帧信息。
getStackTrace()返回一个表示该线程堆栈转储的堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该序列中最新的方法调用。最后一个元素代表堆栈底,是该序列中最旧的方法调用。

public static String getStackTrace() {
        StackTraceElement[] stack = new Throwable().getStackTrace();
        return stack[stack.length - 1].getClassName();
    }

有了基本思路以后,实现起来就没那么困难了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值