但是我們會發現一個問題,如果我們像Hello這樣的類很多,那么,我們是不是要去寫很多個HelloProxy這樣的類呢.沒錯,是的.其實也是一種很麻煩的事.在jdk1.3以后.jdk跟我們提供了一個API?? java.lang.reflect.InvocationHandler的類. 這個類可以讓我們在JVM調用某個類的方法時動態的為些方法做些什么事.讓我們把以上的代碼改一下來看看效果.
同樣,我們寫一個IHello的接口和一個Hello的實現類.在接口中.我們定義兩個方法;代碼如下 :
IHello.java
1
package sinosoft.dj.aop.proxyaop;
2
3
public interface IHello {
4
??/**
5
????? * 業務處理A方法
6
????? * @param name
7
?????*/
8
????void sayHello(String name);
9
??/**
10
????? * 業務處理B方法
11
????? * @param name
12
?????*/
13
????void sayGoogBye(String name);
14
}
15
Hello.java
1
package sinosoft.dj.aop.proxyaop;
2
3
public class Hello implements IHello {
4
5
????public void sayHello(String name) {
6
???????? System.out.println("Hello " + name);
7
???? }
8
????public void sayGoogBye(String name) {
9
???????? System.out.println(name+" GoodBye!");
10
???? }
11
}
12
我們一樣的去寫一個代理類.只不過.讓這個類去實現java.lang.reflect.InvocationHandler接口,代碼如下:
1
package sinosoft.dj.aop.proxyaop;
2
3
import java.lang.reflect.InvocationHandler;
4
import java.lang.reflect.Method;
5
import java.lang.reflect.Proxy;
6
7
public class DynaProxyHello implements InvocationHandler {
8
9
???/**
10
????? * 要處理的對象(也就是我們要在方法的前后加上業務邏輯的對象,如例子中的Hello)
11
?????*/
12
????private Object delegate;
13
14
/**
15
????? * 動態生成方法被處理過后的對象 (寫法固定)
16
????? *
17
????? * @param delegate
18
????? * @param proxy
19
????? * @return
20
?????*/
21
????public Object bind(Object delegate) {
22
????????this.delegate = delegate;
23
????????return Proxy.newProxyInstance(
24
????????????????this.delegate.getClass().getClassLoader(), this.delegate
25
???????????????????????? .getClass().getInterfaces(), this);
26
???? }
27
??/**
28
????? * 要處理的對象中的每個方法會被此方法送去JVM調用,也就是說,要處理的對象的方法只能通過此方法調用
29
????? * 此方法是動態的,不是手動調用的
30
?????*/
31
????public Object invoke(Object proxy, Method method, Object[] args)
32
????????????throws Throwable {
33
???????? Object result = null;
34
????????try {
35
????????????//執行原來的方法之前記錄日志
36
???????????? Logger.logging(Level.DEBUGE, method.getName() + " Method end
.");
37
????????????
38
????????????//JVM通過這條語句執行原來的方法(反射機制)
39
???????????? result = method.invoke(this.delegate, args);
40
????????????//執行原來的方法之后記錄日志
41
???????????? Logger.logging(Level.INFO, method.getName() + " Method Start!");
42
???????? } catch (Exception e) {
43
???????????? e.printStackTrace();
44
???????? }
45
????????//返回方法返回值給調用者
46
????????return result;
47
???? }
48
49
}
50
上面類中出現的Logger類和Level枚舉還是和上一上例子的實現是一樣的.這里就不貼出代碼了.
讓我們寫一個Test類去測試一下.代碼如下:
Test.java
1
package sinosoft.dj.aop.proxyaop;
2
3
public class Test {
4
????public static void main(String[] args) {
5
???????? IHello hello = (IHello)new DynaProxyHello().bind(new Hello());
6
???????? hello.sayGoogBye("Double J");
7
???????? hello.sayHello("Double J");
8
????????
9
???? }
10
}
11
運行輸出的結果如下:
Tue Mar 04 21:24:03 CST 2008 sayGoogBye Method end
.
Double J GoodBye!
2008-3-4 21:24:03 sayGoogBye Method Start!
Tue Mar 04 21:24:03 CST 2008 sayHello Method end
.
Hello Double J
2008-3-4 21:24:03 sayHello Method Start!
由于線程的關系,第二個方法的開始出現在第一個方法的結束之前.這不是我們所關注的!
posted on 2009-07-24 20:40
jadmin 閱讀(87)
評論(0) 編輯 收藏