徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3143字,纯文字阅读大概需要5分钟。
内容图文
第一章:NIO篇>' ref='nofollow'>徒手用Java来写个Web服务器和框架吧<第一章:NIO篇>
第二章:Request和Response>' ref='nofollow'>徒手用Java来写个Web服务器和框架吧<第二章:Request和Response>
这一章先把Web框架的功能说一些,有个雏形。
先是制作一个Service,并绑定到一个正则地址。用到了注解和反射。
项目地址: Telemarketer
Service的定义
Telemarketer的Service是一个服务,请求了跟它关联的地址,那就由它来为你服务。
它对外只需一个方法。并且对这个方法的要求大概只有输入一个Request,可以返回一个Response这么简单。
那就这样
public interface Service { Response execute(Request request); }
问题来了,如何把它关联到uri上呢?第一想法是在创建一个注册中心。
Service的绑定
先来手动挡
新建一个类ServiceRegistry, 在里面放这么一个静态的Map:
privatestatic Map<String, Service> services = new TreeMap<>();
还提供了这么一个方法:
publicstaticvoid register(String pattern, Service service) {services.put(pattern, service);}
然后再提供查找服务的方法。
public static Service findService(String pattern) { for (Map.Entry<String, Service> entry : services.entrySet()) { if (pattern.matches(entry.getKey())) { return entry.getValue(); } } returnnull; }
这样不就根据request确定了服务对象吗?让人们自己动手丰衣足食吧。
然而转念一想,这么搞多麻烦,还得让人专门找个地方register一大堆?这一点都不方便..懒惰是第一大生产力!
那再换个自动挡。
再来自动挡
稍微一想Spring那些框架,用注解搞依赖注入用的那是飞起,Telemarketer也可以!来,说干就干!
先确定注解三个要点
- 确定目标:类
- 确定范围:运行时
- 确定内容:一个String可以放地址正则就好
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface InService { String urlPattern(); }
有了这个,赶紧写个服务先标上。地址正则就匹配根目录吧
1 @InService(urlPattern = "^/$") 2publicclass IndexService implements Service { 3 @Override 4public Response execute(Request request) { 5returnnew FileResponse(Status.SUCCESS_200, PropertiesHelper.getTemplateFile("index.html")); 6 } 7 }
PropertiesHelper.getTemplateFile("index.html") 返回的是一个html的文件,暂时不用管。FileResponse是包含文件内容的Response。
行了,现在想想怎么靠这个注解自动注册呢?
假设我们知道了这个类名是 edu.telemarketer.services.servicesimpls.IndexService 。先反射一个:
Class<?> aClass = Class.forName("edu.telemarketer.services.servicesimpls.IndexService");
注意这里用
Class.forName()
和ClassLoader的load()方法区别:Class.forName()会初始化类中的静态域,有什么static都会准备好,而ClassLoader的load就不会有这样的效果。
弄到这个Class对象后,获取InService标注
InService annotation = aClass.getAnnotation(InService.class);
判断一下是不是null 再判断一下Service.class是不是这个类的接口。如果都满足那就是我们要找的类了。实例化它!注册它!
if (annotation != null && Service.class.isAssignableFrom(aClass)) { Controller.register(annotation.urlPattern(), aClass.asSubclass(Service.class).newInstance()); }
注意这里的 isAssignableFrom 和 instanceof 的差别, isAssignableFrom 左边是右边的父类或者接口。
整个过程就是先获取根目录,然后递归扫描所有.class进行上述判断。而且反射的时候得用全名,那同时再记录一下包路径。具体可以查看源码。
这个过程还遇到了一个问题: 在一开始我获取了edu.telemarketer的包名想转化为路径用的是name.replaceAll("\.", File.separator)。在windows环境下测试出现了一个异常。经过查证后发现,replaceAll是不准出现"\"的,会引起混淆。具体点此处 StackOverflow--replaceAll “/” with File.separator
到此为止自动挡就弄完了。
Controller里的使用
Controller是一个实现了Runnable的类. 它的run里面大概是这么一个过程。
1 Request request = Request.parseFromBuffer(buffer); 2 Service service =ServiceRegistry.findService(request.getFilePath()); 3 Response response = service.execute(request); 4 SelectionKey key = channel.register(selector, SelectionKey.OP_WRITE); 5 key.attach(response);
启动一下,看看页面是不是出来了。
在提交给service处理前和处理后应该由服务器先对头域中的一些信息进行处理,比如维护链接或者添加cookie等等。这些方面后续再来完善。
第三章:Service的实现和注册>' ref='nofollow'>徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>
原文:http://www.cnblogs.com/imyijie/p/4825859.html
内容总结
以上是互联网集市为您收集整理的徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>全部内容,希望文章能够帮你解决徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。