熟悉代理模式的基礎上,首先使用反射實現動態調用某個對象的某個方法,目的就是某個對象某個方法可以進行配置,使用XML或者使用后綴名properties文件。
代碼如下:
1
import java.lang.reflect.Method
2
public class ReflectUtils
{
3
private Class clazz; //目標對象的類
4
private Method method; //目標對象的方法
5
private Object target; //目標對象
6
private Object[] params; //目標方法的參數
7
8
public ReflectUtils(Object targer,String methodName,Object
params)
{
9
locateTarget(target,methodName,params);
10
}
11
public void locateTarget(Object target,String methodName,Object
params)
{
12
this.target = target; //綁定目標對象
13
this.clazz = target.getClass(); //綁定目標對象類
14
locateMethod(methodName,params);
15
}
16
public void locateMethod(String methodName,Object
params)
{
17
this.params=params;
18
Class[] cls = new Class[params.length()];
19
for(int i=0;i<params.length;i++)
{
20
cls[i]=params[i].getClass();
21
}
22
try
{
23
this.method = clazz.getMethod(methodName,cls); //組裝好該方法類
24
}catch(Exception e)
{
25
}
26
}
27
public void invokeMethod()
{
28
try
{
29
this.method.invoke(target,params); //調用該方法
30
}catch(Exception e)
{
31
}
32
}
33
}
34
下面給出測試例子
35
/** *//**
36
*
37
* 定義一個接口
38
**/
39
public interface Crud
{
40
public void add(UserInfo user);
41
public void modify(UserInfo user);
42
public void delete(UserInfo user);
43
}
44
/** *//**
45
*
46
* 接口實現類
47
**/
48
public CrudImpl implements Crud
{
49
public void add(UserInfo user)
{
50
System.out.println("新增用戶:"+new UserInfo("lx","25").getName());
51
}
52
public void modify(UserInfo user)
{
53
System.out.println("修改用戶:"+new UserInfo("lx","25").getName());
54
}
55
public void delete(UserInfo user)
{
56
System.out.println("刪除用戶:"+new UserInfo("lx","25").getName());
57
}
58
}
59
/** *//**
60
*
61
* 定義橫向切面的類
62
**/
63
public class Crosscutting
{
64
public void before()
{
65
System.out.println("前置");
66
}
67
public void after()
{
68
System.out.println("后置");
69
}
70
}
71
/** *//**
72
*
73
* 定義配置文件,使用parameters.properties文件
74
**/
75
method=modify
76
/** *//**
77
*
78
* 定義測試類
79
**/
80
public class Test
{
81
private static Crosscutting cut = new Crosscutting(); // 橫切面的東西,可使用ioc進行配置
82
private static ReflectUtils rf_before = new ReflectUtils(cut, "before");
83
//這個cut就代表AOP里面的橫切面 before代表織入點 同下
84
private static ReflectUtils rf_after = new ReflectUtils(cut, "after");
85
//前置通知
86
public void beforeActive(Object target,String methodName,object
params)
{
87
Class cls = target.getClass();
88
Method[] methods = cls.getDeclaredMethods();
89
for(int i=0;i<methods.length;i++)
{
90
if (methods[i].getName().equals(method))
{
91
rf_before.invokeMethod(); //使用上面自定義動態代理類調用橫切面的before方法
92
new ReflectUtils(obj, method, params).invokeMethod(); //使用上面的動態代理類調用核心目標方法
93
}
94
}
95
}
96
//后置通知
97
public static void afterActive(Object obj, String method, Object
params)
{
98
Class cls = obj.getClass();
99
Method[] methods = cls.getDeclaredMethods();
100
for (int i = 0; i < methods.length; i++)
{
101
if (methods[i].getName().equals(method))
{
102
new ReflectUtils(obj, method, params).invokeMethod();
103
rf_after.invokeMethod();
104
}
105
}
106
}
107
//環繞通知
108
public static void aroundActive(Object obj, String method, Object
params)
{
109
Class cls = obj.getClass();
110
Method[] methods = cls.getDeclaredMethods();
111
for (int i = 0; i < methods.length; i++)
{
112
if (methods[i].getName().equals(method))
{
113
rf_before.invokeMethod();
114
new ReflectUtils(obj, method, params).invokeMethod();
115
rf_after.invokeMethod();
116
}
117
}
118
}
119
//main方法測試
120
public static void main(String[] args) throws Exception
{
121
Crud crud = new CrudImpl(); // 業務bean可使用IOC進行裝配
122
UserInfo user = new UserInfo("lx", "25"); // 實體bean可以使用IOC進行裝配
123
// 讀取配置文件 獲得要攔截的方法名字 相當于XML
124
InputStream is = Test.class.getResourceAsStream("parameters.properties");
125
Properties props = new Properties();
126
props.load(is);
127
String method = props.getProperty("method");
128
beforeActive(crud,method,user); //測試前置通知
129
afterActive(crud,method,user);//測試后置通知
130
//修改parameters.properties文件里面的method名字 比如add modify delete 那么就會對方法實現攔截調用橫切面的方法 以上純屬自我摸索~
131
}
132
}
133
134
}
posted on 2010-08-19 10:33
朔望魔刃 閱讀(497)
評論(0) 編輯 收藏 所屬分類:
設計模式&&數據結構