1. 程式人生 > >理解掌握Struts2Intercept的呼叫過程

理解掌握Struts2Intercept的呼叫過程

本文主要用於理解掌握Struts2 Intercept的呼叫過程 及動態代理

前言:Struts2的 攔截器機制實際上是java設計模式中最重要的設計模式------動態代理  ,   它的需求來源如下:    一個class 有具體的 operation(method)  ,現在有一個需求是: 要在呼叫這個方法呼叫加上 一些業務(比如列印"Today is saturday     ") 在呼叫方法加入一些業務邏輯(比如  Tomorrow is sunday ,so we can play) 好,瞬間的思考可以得到如下實現方法
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 ");//新加業務邏輯 (後)
}

}
這樣雖然也實現了我們想要的效果,但是,這樣的程式碼是高度耦合的,完全不具備重用性,試想下,如果需求變了,現在要在100個方法上加入100個不同的前後呼叫,這樣的程式碼修改量將會是 100的平方的2倍 ,能不能有一種高效的方法,你給我業務邏輯,我就可以完全重用的實現業務邏輯
 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