设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

Netty 实战:如何编写一个麻小俱全的 Web 框架(2)

发布时间:2019-02-20 08:16 所属栏目:21 来源:逅弈
导读:然后我们需要在系统启动的时候,扫描出所有被@Bean注解修饰的类,然后对这些类进行实例化,然后把实例化后的对象保存在一个 Map 中即可,如下图所示: 代码很简单,通过在指定路径下扫描出所有的类之后,把实例对象

然后我们需要在系统启动的时候,扫描出所有被 @Bean 注解修饰的类,然后对这些类进行实例化,然后把实例化后的对象保存在一个 Map 中即可,如下图所示:

Netty 实战:如何编写一个麻小俱全的 Web 框架

代码很简单,通过在指定路径下扫描出所有的类之后,把实例对象加入map中,但是对于已经加入的 bean 不能继续加入了,加入之后要获取一个 Bean 也很简单了,直接通过 name 到 map 中去获取就可以了。

现在我们已经把所有 @Bean 的对象管理起来了,那对于依赖到的其他的 bean 该如何注入呢,换句话说就是将我们实例化好的对象赋值给 @Autowired 注解修饰的变量。

简单点的做法就是遍历 beanMap,然后对每个 bean 进行检查,看这个 bean 里面的每个 setter 方法和属性,如果有 @Autowired 注解,那就找到具体的 bean 实例之后将值塞进去。

setter注入

Netty 实战:如何编写一个麻小俱全的 Web 框架

field注入

Netty 实战:如何编写一个麻小俱全的 Web 框架

通过Aware获取BeanContext

BeanContext 已经实现了,那怎么获取 BeanContext 的实例呢?想到 Spring 中有很多的 Aware 接口,每种接口负责一种实例的回调,比如我们想要获取一个 BeanFactory 那只要将我们的类实现 BeanFactoryAware 接口就可以了,接口中的 setBeanFactory(BeanFactory factory) 方法参数中的 BeanFactory 实例就是我们所需要的,我们只要实现该方法,然后将参数中的实例保存在我们的类中,后续就可以直接使用了。

那现在我就来实现这样的功能,首先定义一个 Aware 接口,所有其他需要回调塞值的接口都继承自该接口,如下所示:

  1. public interface Aware { 
  2.  
  3.  
  4. public interface BeanContextAware extends Aware{ 
  5.  
  6.     /** 
  7.      * 设置BeanContext 
  8.      * @param beanContext BeanContext对象 
  9.      */ 
  10.     void setBeanContext(BeanContext beanContext); 

接下来需要将 BeanContext 的实例注入到所有 BeanContextAware 的实现类中去。BeanContext 的实例很好得到,BeanContext 的实现类本身就是一个 BeanContext 的实例,并且可以将该实例设置为单例,这样的话所有需要获取 BeanContext 的地方都可以获取到同一个实例。

拿到 BeanContext 的实例后,我们就需要扫描出所有实现了 BeanContextAware 接口的类,并实例化这些类,然后调用这些类的 setBeanContext 方法,参数就传我们拿到的 BeanContext 实例。

逻辑理清楚之后,实现起来就很简单了,如下图所示:

Netty 实战:如何编写一个麻小俱全的 Web 框架

Cookie管理

基本上所有的 web 容器都会有 cookie 管理的能力,那我们的 redant 也不能落后。首先定义一个 CookieManager 的接口,核心的操作 cookie 的方法如下:

  1. public interface CookieManager { 
  2.  
  3.     Set<Cookie> getCookies(); 
  4.  
  5.     Cookie getCookie(String name); 
  6.      
  7.     void addCookie(String name,String value); 
  8.  
  9.     void setCookie(Cookie cookie); 
  10.  
  11.     boolean deleteCookie(String name); 
  12.  

其中我只列举了几个核心的方法,另外有一些不同参数的重载方法,这里就不详细介绍了。最关键的是两个方法,一个是读 Cookie 一个是写 Cookie 。

读 Cookie

Netty 中是通过 HttpRequest 的 Header 来保存请求中所携带的 Cookie的,所以要读取 Cookie 的话,最关键的是获取到 HttpRequest。而 HttpRequest 可以在 ChannelHandler 中拿到,通过 HttpServerCodec 进行编解码,Netty 已经帮我们把请求的数据转换成 HttpRequest 了。但是这个 HttpRequest 只在 ChannelHandler 中才能访问到,而处理 Cookie 通常是用户自定义的操作,并且对用户来说他是不关心 HttpRequest 的,他只需要通过 CookieManager 去获取一个 Cookie 就行了。

这种情况下,最适合的就是将 HttpRequest 对象保存在一个 ThreadLocal 中,在 CookieManager 中需要获取的时候,直接到 ThreadLocal 中去取出来就可以了,如下列代码所示:

  1. @Override 
  2. public Set<Cookie> getCookies() { 
  3.     HttpRequest request = TemporaryDataHolder.loadHttpRequest(); 
  4.     Set<Cookie> cookies = new HashSet<>(); 
  5.     if(request != null) { 
  6.         String value = request.headers().get(HttpHeaderNames.COOKIE); 
  7.         if (value != null) { 
  8.             cookies = ServerCookieDecoder.STRICT.decode(value); 
  9.         } 
  10.     } 
  11.     return cookies; 

TemporaryDataHolder 就是那个通过 ThreadLocal 保存了 HttpRequest 的类。

写 Cookie

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读