熟悉代理模式的基础上,首先使用反射实现动态调用某个对象的某个方法,目的就是某个对象某个方法可以进行配置,使用XML或者使用后缀名properties文件。
代码如下:
1import java.lang.reflect.Method
2public 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(){
28try{
29 this.method.invoke(target,params); //调用该方法
30 }catch(Exception e){
31 }
32}
33}
34下面给出测试例子
35/** *//**
36 *
37 * 定义一个接口
38 **/
39public 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 **/
48public 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 **/
63public 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 **/
75method=modify
76/** *//**
77 *
78 * 定义测试类
79 **/
80public 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方法测试
120public 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
朔望魔刃 阅读(488)
评论(0) 编辑 收藏 所属分类:
设计模式&&数据结构