背景:
攔截器是現在很多程序必須的一個東西。比如要在某個方法的前后做些處理,在一些特定的情況下可能會導致大量的重復代碼。而假如我們擁有了類似攔截器一樣的東西,那我們就可以任意在自己希望的方法的執行前后做我們自己的處理,比如日志,取得參數或者是事務等。
實現:
1.首先定義一個業務接口
1
/** *//**
3
* 一個業務對象接口,所有的業務操作都應該在execute方法中去執行
7
* @author Administrator
11
*/
12
13
public interface Action
{
14
15
public void execute();
21
}
22


3

7

11

12

13



14

15

21

22

2 定義一個攔截器接口
1
/** *//**
2
3
* 攔截器接口,可以在方法前后執行操作
7
* @author Administrator
11
*/
13
public interface Interceptor
{
16
17
/** *//**
19
* 初始化方法,根據需要實現
22
23
*/
24
25
void init();
28
29
/** *//**
30
31
* 終結方法,根據需要實現
35
*/
36
37
void destory();
40
41
/** *//**
42
43
* 攔截器的具體實現
47
* @param invocation 一個Action 的包裝對象,以后修改為能指定任意對象
49
* @return 一個狀態
51
* @throws Exception
53
*/
55
String intercept(ActionInvocation invocation) throws Exception;
57
}
58


2

3

7

11

13



16

17


19

22

23

24

25

28

29


30

31

35

36

37

40

41


42

43

47

49

51

53

55

57

58

3 實現一個默認的攔截器
1
/** *//**
2
3
* 攔截器接口,可以在方法前后執行操作
7
* @author Administrator
11
*/
12
13
public interface Interceptor
{
17
/** *//**
19
* 初始化方法,根據需要實現
23
*/
25
void init();
29
/** *//**
31
* 終結方法,根據需要實現
35
*/
36
37
void destory();
41
/** *//**
43
* 攔截器的具體實現
47
* @param invocation 一個Action 的包裝對象,以后修改為能指定任意對象
49
* @return 一個狀態
51
* @throws Exception
53
*/
54
55
String intercept(ActionInvocation invocation) throws Exception;
56
57
}
58


2

3

7

11

12

13



17


19

23

25

29


31

35

36

37

41


43

47

49

51

53

54

55

56

57

58

4 實現一個Action接口的包裝器,這里實現了攔截器的核心方法
1
/** *//**
2
3
* 默認實現
5
* @author Administrator
9
*/
10
11
public class DefaultActionInvocation implements ActionInvocation
{
12
13
private Object action;
17
private Iterator interceptors;
21
DefaultActionInvocation(Object action, List interceptors)
{
23
this.action = action;
27
this.interceptors = interceptors.iterator();
29
}
33
public Object getAction()
{
35
return action;
37
}
38
39
40
41
public void setAction(Object action)
{
43
this.action = action;
45
}
49
public Iterator getInterceptors()
{
51
return interceptors;
53
}
57
public void setInterceptors(Iterator interceptors)
{
59
this.interceptors = interceptors;
61
}
67
/** *//**
69
* 調用攔截器
71
*/
72
73
public String invoke() throws Exception
{
74
75
if (interceptors.hasNext())
{
77
Interceptor interceptor = (Interceptor) interceptors.next();
79
interceptor.intercept(this);
81
} else
{
83
this.invokeActionOnly();
85
}
89
return null;
91
}
92
93
94
95
public String invokeActionOnly() throws Exception
{
97
return invokeAction(getAction());
99
}
100
101
/** *//**
103
* 調用Action的execute
105
* @param action
107
* @return
109
*/
111
private String invokeAction(Object action)
{
113
if (action instanceof Action)
{
115
Action instance = (Action) action;
117
instance.execute();
119
}
121
return null;
123
}
127
}
128
129


2

3

5

9

10

11



12

13

17

21



23

27

29

33



35

37

38

39

40

41



43

45

49



51

53

57



59

61

67


69

71

72

73



74

75



77

79

81



83

85

89

91

92

93

94

95



97

99

100

101


103

105

107

109

111



113



115

117

119

121

123

127

128

129

5 如何使用?
1
/** *//**
2
3
* 定義的一個業務對象
7
* @author Administrator
11
*/
12
13
public class MyAction implements Action
{
14
15
/** *//**
17
* 執行一個業務操作,這里是print操作
19
*/
20
21
public void execute()
{
23
System.out.println("執行業務邏輯…");
25
}
31
/** *//**
32
33
* client調用的方式
35
* @param args
37
* @throws Exception
39
*/
40
41
public static void main(String[] args) throws Exception
{
42
43
Action a = new MyAction();
44
45
// 定義2個攔截器
46
47
Interceptor i1 = new L1(); //繼承了AbstractInterceptor的一個攔截器
49
Interceptor i2 = new L2(); //繼承了AbstractInterceptor的一個攔截器
51
// Interceptor i3 = new L2();
52
53
List interceptors = new ArrayList();
54
55
interceptors.add(i1);
57
interceptors.add(i2);
58
59
// 設置攔截器
61
ActionInvocation myaction = new DefaultActionInvocation(a, interceptors);
62
63
//執行
65
myaction.invoke();
66
67
}
71
}
72
73


2

3

7

11

12

13



14

15


17

19

20

21



23

25

31


32

33

35

37

39

40

41



42

43

44

45

46

47

49

51

52

53

54

55

57

58

59

61

62

63

65

66

67

71

72

73

可以改進的地方:
1) 可以使用動態代理,這樣就可以對任意對象使用攔截器了。而不僅僅是Action接口
2) 攔截器可以通過一個配置文件讀取,比如一個XML文件,而不是現在這樣寫死在客戶端代碼中。Digester給我們提供了解析XML的幫助
3)可以使用Commons Collections 里的ResettableIterator,這樣每次Iterator就可以reset了,不然我們只有每次都使用新的ActionInvocation