理解掌握Struts2Intercept的呼叫過程
本文主要用於理解掌握Struts2 Intercept的呼叫過程 及動態代理
前言:Struts2的 攔截器機制實際上是java設計模式中最重要的設計模式------動態代理 , 它的需求來源如下: 一個class 有具體的 operation(method) ,現在有一個需求是: 要在呼叫這個方法呼叫前加上 一些業務(比如列印"Today is saturday ") 在呼叫方法後加入一些業務邏輯(比如 Tomorrow is sunday ,so we can play) 好,瞬間的思考可以得到如下實現方法這樣雖然也實現了我們想要的效果,但是,這樣的程式碼是高度耦合的,完全不具備重用性,試想下,如果需求變了,現在要在100個方法上加入100個不同的前後呼叫,這樣的程式碼修改量將會是 100的平方的2倍 ,能不能有一種高效的方法,你給我業務邏輯,我就可以完全重用的實現業務邏輯class proxy{ public static void myMetod(){ System.out.println("Today is saturday ");//新加業務邏輯 (前) System.out.println("we can't play any more"); //原來的業務需要列印的是we can't play any more System.out.println(" Tomorrow is sunday ,so we can play ");//新加業務邏輯 (後) } }
AOP 程式設計, (aspect to programing ) 為此而生。
想要達到的效果如下
class DynamicProxy{ public static void main(String[] arg){ DynamiPproxy dynamicproxy =new DynamiPproxy(proxy.myMethod(), beforeMethod(), AfterMethod()); //第一個引數是原來方法,第二個引數是業務呼叫前執行方法,第三個引數是業務呼叫鉤執行方法 dynamicproxy.invoke(); //呼叫 // 這裡dynamicproxy就是 原來proxy的一個動態代理,它會根據後面的三個引數生成一個類, 裡面有 一個方法, 和上面proxy類中的myMethod方法體一樣,然後執行 invoke 方法! //慶幸的是這一切都有人已經幫我們寫好,並出書育人:java設計模式 // 這樣我們就可以只修改 引數的具體實現 ,就可以非常解耦的實現我們的AOP需求 } public void beforeMethod(){ System.out.println("Today is saturday ");//新加業務邏輯 (前) } public void before AfterMethod(){ System.out.println(" Tomorrow is sunday ,so we can play ");//新加業務邏輯 (後) } }
具體的動態代理實現可以看其他部落格
http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html
http://blog.csdn.net/heyutao007/article/details/49738887
我們再來看Struts2的攔截器
以下是例子
Struts.xml攔截器定義如下
<package name="interceptor" extends="struts-default"> <!-- 定義多個攔截器 --> <interceptors> <!-- 定義一個攔截器 --> <interceptor name="my1" class="com.baizhi.action2.MyInterceptor"></interceptor> <interceptor name="my2" class="com.baizhi.action2.MyInterceptor2"></interceptor> <!-- 定義一個攔截器棧 --> <interceptor-stack name="myStack"> <interceptor-ref name="my2"></interceptor-ref> <interceptor-ref name="my1"></interceptor-ref> </interceptor-stack> <global-results> <result name="error">/error.jsp</result> </global-results> <action name="aAction" class="com.baizhi.action2.AAction"> <interceptor-ref name="myStack"></interceptor-ref> <result name="success">/index.jsp</result> </action>
AAction.java
publicclass AAction implements Action{
public String execute() throws Exception { System.out.println("this is AAction!!!");
return"AAction";
}
}
MyInterceptor2.java
publicclassMyInterceptor2implements Interceptor {
publicvoid destroy() {
// TODO Auto-generated method stub
System.out.println("MyInterceptor2 結束");
}
publicvoidinit() {
System.out.println("MyInterceptor2 初始化");
}
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("this is MyInterceptor22222!!");
System.out.println(" MyInterceptor2 ai.invoke()="+ai.invoke()+"ai.getAction()="+ai.getAction());
return"MyInterceptor2";
}
}
MyInterceptor.java
package com.baizhi.action2;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
public void destroy() {
}
public void init() {
}
public String intercept(ActionInvocation ai) throws Exception {
//共有的部分
//1 讓程式通過攔截器
System.out.println("this is myinterceptor 1111");
//ai.invoke();
System.out.println(" MyInterceptor2 ai.invoke()="+ai.invoke()+"ai.getAction()="+ai.getAction());
//攔截響應
System.out.println("this is myinterceptor end!!!!");
//2. 通過ai獲取值棧物件
/*ValueStack vs = ai.getStack();
vs.setValue("#request.name", "haoge");
System.out.println(vs.findValue("#request.name"));
ValueStack vs = ActionContext.getContext().getValueStack();*/
return "MyInterceptor";
}
}
呼叫過程
值得注意的是:<default-interceptor-ref>預設攔截器和普通攔截器如果同用一個類,將生成兩個代理例項
輸出結果
this is MyInterceptor22222!!
this is myinterceptor 1111
this is AAction!!!
MyInterceptor2 ai.invoke()=errorai.getAction()[email protected]
this is myinterceptor end!!!!
MyInterceptor2 ai.invoke()=MyInterceptorai.getAction()[email protected]
相關推薦
理解掌握Struts2Intercept的呼叫過程
本文主要用於理解掌握Struts2 Intercept的呼叫過程 及動態代理 前言:Struts2的 攔截器機制實際上是java設計模式中最重要的設計模式------動態代理 , 它的需求來源
【18.7.27】函式呼叫過程的深度理解(棧幀)
函式可以大大減少我們程式的程式碼量,使程式碼寫起來更加的簡潔,使程式碼思路更加清晰。是我們程式猿在編寫程式碼時必不可少的。 那麼函式的呼叫過程就非常的重要,今天讓我們來從一個深的角度去了解一下函式的呼叫過程。 函式的呼叫過程也可以叫做棧幀 棧幀的定義是:棧幀也叫過程活動記錄,
dubbo原始碼理解(2)消費者呼叫過程
又過了很久才敢寫。自己也在反覆看,consumer在啟動時是如何建立代理並注入的呢? 在第一篇 我寫了一些bean的載入過程。這個過程也是包含在啟動過程中的。 one、spring 載入dubbo檔案,開始解析consumer 配置檔案。目的 就是注入。但這時候還沒有物件可以注入。只是有這個
Dubbo原始碼理解(3) 消費者呼叫過程
小弟一直苦思 consumer 與provider 到底是怎麼通訊的呢,與是從網上找了一篇,覺得寫得很靠譜。自己就算總結,也未必有這個好,所以記錄下來!! 消費者呼叫流程涉及到消費者端和生產者端的互動,所以將分為三個部分來講解,分別是 -消費者發起呼叫請求 -生產者響應呼叫請求 -消費者獲取呼叫
深入理解C語言的函式呼叫過程
本文主要從程序棧空間的層面複習一下C語言中函式呼叫的具體過程,以加深對一些基礎知識的理解。 先看一個最簡單的程式: 點選(此處)摺疊或開啟 /*test.c*/ #include <stdio.h> int foo1(
c語言函式呼叫過程中棧的工作原理理解
差不多每個程式設計師都知道,函式呼叫過程,就是層層入棧出棧的過程。 那麼這個過程中的詳細的細節是什麼樣子的呢? 閱讀了以下幾篇文章之後,對整個過程基本理解了: C函式呼叫過程原理及函式棧幀分析 閱讀經典——《深入理解計算機系統》04 函式返回值與棧 針對自己的理解,做個記錄:
深入理解遞迴函式的呼叫過程
int main(void){ unsigned long number; printf("Enter an integer(q to quit):/n"); while(scanf("%ul",&number)==1) { printf("Binary equivalent :");
函式呼叫過程理解
一、棧 棧是常見的資料結構,在發生程式呼叫的情況下,作業系統會為被呼叫的子程式開闢一塊棧空間。棧除了先入後出(FILO)外還有以下特性:每一個程序在使用者態對應一個呼叫棧結構(call stack) 程式中每一個未完成執行的函式對應一個棧幀(stack fram
字符編碼詳解——徹底理解掌握編碼知識,“亂碼”不復存在
想法 3.3 無符號 orm 微軟公司 詳解 表示 xxxxxx 全部 每一個程序員都不可避免的遇到字符編碼的問題,特別是做Web開發的程序員,“亂碼問題”一直是讓人頭疼的問題,也許您已經很少遇到“亂碼”問題,然而,對解決亂碼的方法的內在原理,您是否明白?本人作為一個程序員
對OpenCV中3種乘法操作的理解掌握
alt 函數 opencv 如果 csdn tle 基本操作 art sca 參考了《Opencv中Mat矩陣相乘——點乘、dot、mul運算詳解 》“http://blog.csdn.net/dcrmg/article/details/52404580”的相關內容。乘法是
arm linux 系統呼叫過程
在Linux下系統呼叫是用軟中斷實現的,下面以一個簡單的open例子簡要分析一下應用層的open是如何呼叫到核心中的sys_open的。 t8.c 1: #include <stdio.h> 2: #include <sys/types.h> 3:
Java中的方法呼叫過程分析
假設呼叫x.f(args),隱式引數x宣告為類C的一個例項物件: 1.編譯器檢視物件的宣告型別和方法名。例如,可能存在方法f(int)和方法f(String)。編譯器將會一一列舉出所有該類中名為f的方法和其超類中訪問屬性為public且名為f的方法。 2.編譯器將檢視呼叫方法時提供的引數型別
WebService—CXF整合Spring實現介面釋出和呼叫過程
CXF整合Spring實現介面釋出 釋出過程如下: 1、引入jar包(基於maven管理) <dependency> <groupId>org.apache.cxf</groupId> <artifactId>
Spring Cloud微服務的簡單組成和呼叫過程
學習微服務的過程中,很多東西都會忘,所以就畫了一個微服務的圖,其實之前我也畫過微服務的圖,但是沒有這個詳細,希望能幫到正在開始學習微服務的人吧! 其實微服務很簡單就像你去足療店一樣,你不知道怎麼去,第一次,怎麼辦,你求助你的朋友,你的朋友經常去,所以你的
函式的呼叫過程詳解———棧幀的建立和銷燬
●回顧內容: 函式的定義:函式是一個程式中的部分程式碼,由一個或多個語句組成,它的功能是實現某些特定的任務。函式相對於其他程式碼來說具備相對的獨立性。 函式的呼叫:在某個函式內部,使用另一個函式來完成相關的任務,這個過程叫做函式呼叫。 那麼函式是如何呼叫的呢?分析一段簡單的程式碼:
高階語言反彙編程式的函式呼叫過程
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
dubbo的服務呼叫過程
服務消費的過程:referenceConfig類的init方法呼叫Protocol的refer方法,生成invoker例項,然後把Invoker轉換為客戶端需要的介面。 2、原始碼解析 dubbo的消費端初始化在ReferenceConfig的get()方法 public
追蹤shell呼叫過程-strace--效能優化與測試
追蹤shell呼叫過程-strace–效能優化與測試 strace可以追蹤shell呼叫的過程。 可以用來優化相關內容 具體效能優化與測試轉自https://blog.csdn.net/z1134145881/article/details/52079836 Mark
iOS進階—Runtime:OC方法底層呼叫過程
GitHub參考 PS:參考GitHub分享的Runtime002程式碼 iOS進階—目錄 OC方法底層呼叫過程 如果檢視OC的底層呼叫過程,我們需要藉助clang工具 使用終端 cd 專案目錄 clang -rewrite-objc main.m 會生成
Dubbo呼叫過程監控
MonitorFilter 主要對呼叫過程進行監控, public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { if(invoker.ge