反射实现动态初始化责任链

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介:

有一个DNS服务器项目(其实是最近在做的一个智能DNS项目)的过滤模块,现有如下需求:1.能准确判断出用户IP地址是否合法,及用户IP是否位于黑名单中;2.用户请求查询的主机名是否合法,机主机名是否位于黑名单中。要实现对以上用户请求过滤。后期可能还要实现对ddos攻击请求的过滤。由于前一段时间了解了一下责任链模式,所以决定用责任链模式实现该模块。类结构图如下所示(图画的不一定准确,凑合着看吧):

clip_image002[7]

图中有一个抽象类Filter,他有一个抽象方法Validate(),用于实现对请求的过滤。其他类均继承自Filter类。其中IPFilter实现对IP过滤,DomainNameFilter实现对主机名的过滤。DDOsFilter实现对DDOs请求过滤,暂时未使用。FilterChain中有一个List<Filter> 类型对象filterChain用于存放各个过滤器。还有一个Add()方法用来向filterChain中添加过滤器。

现在由于没有新的需求,采用的是静态的去初始化filterChain。方法如下:

public   FilterChain   Add ( Filter   filter ) 

{ 
     filterChain . Add ( filter ) ; 
     return   this ; 
} 
7

然后,可以像下面一样去调用这个方法:

FilterChain   fc   =   new   FilterChain ( ) ; 
fc . Add ( new   IPFilter ( ) ) . Add ( new   DomainNameFilter ( ) ) . Add ( new   DDosFilter ( ) ) ; 
3

OK,现在只需调用fc.Validate(),就可以实现对IP和主机名的过滤。

似乎,我们已经实现该模块的功能了,而且用着也挺简单,调用时完全不需要知道过滤具体是怎么实现的。很完美,所以经测试之后我们将系统发布到服务器上开始工作。

但是,我们似乎忽略了一点。假如现在我们发现有用户发送恶意请求企图攻击我们的服务器,导致我们的服务器不能正常的为其他用户提供服务。我们当然不能容忍这种行为,更不能让攻击者得逞。所以我们要将DDosFilter也投入使用来时我们的系统更加强壮。

What should we do?

我们需要修改代码。如上面的fc.Add().Add().Add(),我们可以再在后面加一个Add().

OK,问题解决了。

假如,现在又有新的需求,主机名过滤不在那么重要了,要将其去掉。

怎么做?

正如上面我们需要修改代码来完成工作。但是慢慢的我们会发现,我们每次都需要修改代码,而且每次只是需要修改一丁点儿的代码。但是我们的系统已经正式发布了,每次只为这么一点小事就修改代码,会显示出我们的系统不够强壮。而且每次的一丁点的修改,也使我们的工作看起来似乎没什么意义。

我们寻求更加简便的方法来完成对系统的更改。于是我们想到了配置文件。我们可以将要使用的过滤器写入配置文件中,这样只需修改配置文件就可以完成对系统的更改,而无需修改代码。

最近,看了看反射(虽然课堂上老师说只是了解即可,可我的直觉告诉我这个东西可以多了解一些,它很有用),它完全可胜任这一工作。当然还会有其他方法。但本文只探讨用反射机制实现。于是产生了如下面的代码:

1   private   FilterChain   DynamicAdd ( ) 
2  
3   { 
4        string   fileContent   =   File . ReadAllText ( " Filter.config " ) ;

 


5        string [ ]   filters   =   fileContent . Trim ( ) . Split ( ' ; ' ) ;

 


6        Assembly   ass   =   Assembly . GetExecutingAssembly ( ) ;

 


7        Type [ ]   types   =   ass . GetTypes ( ) ;

 


8        object   obj   =   null ;

9        foreach   ( var   item   in   filters ) 
10            {

 


11            try 
12                 {

 


13                      obj   =   ass . CreateInstance ( item . Trim ( ) ) ;

 


14                 }

 


15            catch   ( Exception ) 
16                 {

 


17                      continue ;

 


18                 } 
19                 if   ( obj   ! =   null )
                    {

 


20                             filterChain . Add ( ( Filter ) obj ) ; 
21                      }
            }

22                      return   this ; 
23        } 
24

其中,需要加载的过滤器放在filter.config这个文件中。格式如下:

Filter.IPFilter;Filter.DomainNameFilter;Filter.DDosFilter

      从配置文件中可以读出过滤器的名称,然后通过反射构造出对应过滤器的对象,然后将对象加入filterChain中,从而实现filterChain的动态初始化。

      对于过滤规则,一个系统有一组就够了,所以可以进一步将filterChain声明为 private static List<Filter> 类型,然后在类构造器而不是实例构造器中去动态初始化它。这样在过滤时就完全不需要去考虑初始化过滤链的事儿了。当过滤需求放生变化时,只需修改配置文件,然后重启一下服务即可。进而摆脱频繁修改代码的烦恼。


本文转自HDDevTeam 51CTO博客,原文链接:http://blog.51cto.com/hddev/622944,如需转载请自行联系原作者

相关文章
|
JavaScript
JS自动生成速记符、拼音简写/拼音的声母(例如:“你挚爱的强哥”转换为“NZADQG”)。提取首字母,返回大写形式;提取拼音, 返回首字母大写形式(全拼)。
JS自动生成速记符、拼音简写/拼音的声母(例如:“你挚爱的强哥”转换为“NZADQG”)。提取首字母,返回大写形式;提取拼音, 返回首字母大写形式(全拼)。
14437 0
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
MarS:微软开源金融市场模拟预测引擎,支持策略测试、风险管理和市场分析
MarS 是微软亚洲研究院推出的金融市场模拟预测引擎,基于生成型基础模型 LMM,支持无风险环境下的交易策略测试、风险管理和市场分析。
277 8
MarS:微软开源金融市场模拟预测引擎,支持策略测试、风险管理和市场分析
|
人工智能 Java 测试技术
JDK11下Mock框架进化:从PowerMockito到Mockito Only
本文探讨了从使用PowerMock的测试环境迁移到仅使用Mockito(Mockito Only)策略的必要性和实践方法。
420 10
|
测试技术
单元测试策略问题之行覆盖率和分支覆盖率之间的问题如何解决
单元测试策略问题之行覆盖率和分支覆盖率之间的问题如何解决
539 7
|
10月前
|
Java 开发者
深入理解BigDecimal:精度保障的秘诀
【10月更文挑战第29天】
341 5
|
前端开发 架构师 算法
技术一号位的方法论《个人篇》——人成长的本质以及如何构建个人成长路线图
不论你是职场新人还是35岁的职场“老人”,成长是每个职场人都绕不开的话题,同时也是贯穿每个人职业生涯的痛点。本文主要帮助读者建立起对个人成长的认知,然后在此认知的基础上让大家理解成长的本质,最终通过文章的引导,来帮助读者完成个人成长路线图的确定以及落地实践。
13779 3
技术一号位的方法论《个人篇》——人成长的本质以及如何构建个人成长路线图
|
Java 测试技术 API
解决Java中不同版本兼容性问题
解决Java中不同版本兼容性问题
|
Kubernetes JavaScript API
如何理解 Istio Ingress, 它与 API Gateway 有什么区别?东西流量?南北流量?
这三者都和流量治理密切相关,那么流量治理在过去和现在有什么区别呢?都是如何做的呢? 在学习istio的时候对流量管理加深了理解。什么是东西流量?什么是南北流量?
508 0
|
计算机视觉
【目标跟踪】卡尔曼滤波器(Kalman Filter) 含源码
【目标跟踪】卡尔曼滤波器(Kalman Filter) 含源码
623 0
|
Java 开发者
Java文档注解中@link与@see的使用详解
Java文档注解中@link与@see的使用详解
1626 0