`
piecehealth
  • 浏览: 47585 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Before_filter的实现。

 
阅读更多
突然想起rails有before_filter,想了一下怎么实现(看源码太费劲,机器上也没rails),就动手试了一下。

简单介绍一下before_filter:

比如以下代码:
class Person
	
	before :bef
	after :aft
	
	def initialize name
		@name = name
	end
	
	def make_new_friend
		puts "Nice to see you"
	end
	
	def  introduce_self
		puts "Bla Bla Bla..."
	end
	
	def bef
		puts "Hi, I'm #{@name}"
	end
	
	def aft
		puts "Bye, contact me, I'm #{@name}"
	end
		
end

p =Person.new('Xiao Ping')

p.make_new_friend
p.introduce_self


我想每次运行Person的某个方法前,都自动执行一下bef方法(在第3行声明过,在18行定义),运行方法后执行aft方法。(例如rails中可以在bef方法中写验证用户是否有效),既方法make_new_friend
虽然目前看只输出Nice to see you,但是我实际要输出
Hi, I'm Xiao Ping
Nice to see you
Bye, contact me, I'm Xiao Ping

bef
make_new_friend
aft
三个方法的组合。

实现的方式我目前猜测了几种,并自己写了一种供大家分享。
原理很简单,就是通过method_added这个钩子方法hack新添加的方法
class Base

	def self.method_added m
		m_name = m.to_s
		# 下面几个判断都是过滤掉不需要hack的方法。
		@@registered_methods ||= []
		unless m_name =~ /original/ || m_name == 'initialize'
			unless protected_instance_methods.include?(m)
				unless @@registered_methods.include?(m_name)
					
					# 保存原来的方法
					alias_method "original_#{m_name}".to_sym, m_name.to_sym 
					@@registered_methods << m_name
					self.class_eval do
						parameters = public_instance_method(m).parameters.collect {|i| i[1]}
						
						# 创建新的同名方法
						define_method m do |*parameters| 
							self.class.class_variable_get(:@@before).each do |m|
								__send__(m)
							end
							rtn = __send__("original_#{m_name}".to_sym, *parameters)
							self.class.class_variable_get(:@@after).each do |m|
								__send__(m)
							end
							rtn
						end					
					end
				end
			end
		end
	end
	
	def self.before *methods
		@@before ||= []
		methods.each do |m|
			@@before << m unless @@before.include?(m)
		end
	end
	
	def self.after *methods
		@@after ||= []
		methods.each do |m|
			@@after << m unless @@after.include?(m)
		end
	end

end

class Person < Base
	
	before :bef
	after :aft
	
	def initialize name
		@name = name
	end
	
	def make_new_friend
		puts "Nice to see you"
	end
	
	def  introduce_self
		puts "Bla Bla Bla..."
	end
	
	
	protected
	def bef
		puts "Hi, I'm #{@name}"
	end
	
	def aft
		puts "Bye, contact me, I'm #{@name}"
	end
		
end

p =Person.new('Xiao Ping')

p.make_new_friend
p.introduce_self


有点瑕疵,改了之后容易让人confused,所以就没改,希望能对大家有帮助。
分享到:
评论

相关推荐

    基于Servlet实现 Filter 拦截器

    编写 Servlet 并添加两个 Filter,并确保在 Servlet 执行之前和之后...在此方法中,您可以编写逻辑,例如打印 "Filter01 before",并在处理完请求后打印 "Filter01 after"。 创建第二个 Filter,将其命名为 Filter02

    Filter的使用的demo

    在这个“Filter的使用的demo”中,我们将深入探讨`Filter`与`ListActivity`的结合应用,以及如何实现自定义过滤器。 `ListActivity` 是 Android 提供的一个特殊类型的 Activity,专门用于展示列表数据。它简化了在...

    filter过滤关键字

    5. **实现过滤的工具和技术**:在Web开发中,常用的有Java的Servlet Filter、JavaScript的DOM事件监听和过滤、Python的Flask框架中的`@app.before_request`装饰器等。在数据库查询中,可以利用SQL的WHERE子句配合...

    STRUTS:filter过滤器

    ### STRUTS:filter过滤器 #### 概述 在Java Web开发中,过滤器(Filter)是一种重要的组件,用于拦截客户端发送至服务器的请求或服务器返回至客户端的响应。Struts框架作为Java Web开发中的一种流行框架,利用了...

    过滤器(filter) 例子源码

    System.out.println("Filter Before"); // 继续传递请求到下一个过滤器或目标Servlet chain.doFilter(request, response); // 在请求离开目标Servlet之后执行的操作 System.out.println("Filter After"); } ...

    Laravel开发-filter

    })-&gt;before('xss.filter'); ``` 二、防止XSS攻击 1. **使用内置的` Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull `**:Laravel已经内置了一个中间件来处理空字符串,可以减少XSS风险。在`...

    Spring_Security_多页面登录配置教程

    &lt;sec:custom-filter before="AUTHENTICATION_PROCESSING_FILTER"/&gt; &lt;property name="filterProcessesUrl" value="/shop/login_action"/&gt; !loginSuccess.action"/&gt; !loginError.action"/&gt; &lt;!-- 管理员登录...

    PopupWindow实现筛选框

    public void onTextChanged(CharSequence s, int start, int before, int count) { // 根据输入更新ListView的数据源 } @Override public void afterTextChanged(Editable s) { } }); ListView filterList =...

    Magento Events CheatSheet (Magento事件速查表)

    Mage::dispatchEvent('adminhtml_widget_grid_filter_collection', array('collection' =&gt; $collection, 'filter' =&gt; $filter)); ``` #### 8. adminhtml_widget_form_before_tohtml **位置:** Form.php(第 141 ...

    android 实现列表搜索

    本篇将详细介绍如何在Android应用中实现列表搜索,主要涉及`filter`概念以及实际的代码实现。 一、Filter原理 `Filter`是Java和Android中的一个接口,用于数据过滤。在Android中,`Filter`通常与`Adapter`一起使用...

    Laravel开发-laravel-filter

    这通常通过 `before` 和 `after` 钩子实现,这两个钩子分别在路由处理之前和之后运行。 创建过滤器的步骤如下: 1. **注册过滤器**:在 `app/Http/Kernel.php` 文件中,你可以看到一个 `$routeMiddleware` 数组,...

    详解在Spring-Boot中实现通用Auth认证的几种方式

    首先,我们需要定义一个过滤器类 `AuthFilter`,该类需要实现 `Filter` 接口。然后,我们在 `doFilter()` 方法中判断是否需要认证,如果需要,则执行认证逻辑。 在 web.xml 文件中,我们需要注册该过滤器,以便它...

    Flask框架各种常见装饰器示例

    在示例中还提到了自定义before和after函数,这不完全等同于Flask内置的装饰器,但通过编写这些函数,可以实现类似的功能。例如,在before函数中,可以编写登录验证逻辑,如果用户没有会话信息,则可以重定向到登录...

    JTTK functional description

    通过这些API,开发者可以利用OpenGL或其他图形库实现JT文件的渲染与显示,进而可以在自己开发的应用程序中加入JT文件处理能力。 文档的详细描述部分涉及到3D建模、产品制造信息(PMI)等方面的内容。3D建模是通过JT...

    利用 CSS 实现漂亮的毛玻璃效果

    为了实现更好的浏览器兼容性,可以结合使用`::before`伪元素的`filter`方法。 HTML方面,你可能会有一个包含内容的容器,比如这样: ```html 你的标题 你的内容 ``` 在这个例子中,`.frosted-glass`是应用毛...

    实现ListView过滤功能,继承于BaseAdapter,非ArrayAdapter。

    public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(s); } // ... 其他TextWatcher方法 }); } } ``` 以上就是如何在不使用ArrayAdapter的情况下,...

    kalman_GPS_INS_position_sp_NFb_卡尔曼滤波_beforelhv_kalman_

    标题“kalman_GPS_INS_position_sp_NFb_卡尔曼滤波_beforelhv_kalman_”涉及的是一个使用卡尔曼滤波(Kalman Filter)优化GPS与惯性导航系统(INS)融合定位的问题。在实际的导航应用中,GPS提供全球定位信息,而INS...

    tbd算法动态规划实现

    其中包含了仿真场景的设置,主要参考了D.J.Samlond的a partilce filter for track-before-detect文章中的仿真场景和目标量测模型,动态规划算法的实现主要参照了电子科技大学易伟博士的博士论文。

    Acegi入门资料

    - **FilterToBeanProxy**:Acegi通过实现了`Filter`接口的`FilterToBeanProxy`类提供了一种特殊的方式来使用Servlet Filter。该类委托Spring中的`Bean`——`FilterChainProxy`来完成过滤功能。 - `&lt;filter&gt;`:定义...

Global site tag (gtag.js) - Google Analytics