熟悉代理模式的基础上,首先使用反射实现动态调用某个对象的某个方法,目的就是某个对象某个方法可以进行配置,使用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
朔望魔刃 阅读(495)
评论(0) 编辑 收藏 所属分类:
设计模式&&数据结构