然后我們要改一下代理對象DynaProxyHello中的代碼.如下:1
packagesinosoft.dj.aop.proxyaop;
2
3
importjava.lang.reflect.InvocationHandler;
4
importjava.lang.reflect.Method;
5
importjava.lang.reflect.Proxy;
6
7
publicclassDynaProxyHelloimplementsInvocationHandler{
8
??/**
9
????? * 操作者
10
?????*/
11
????privateObject proxy;
12
??/**
13
????? * 要處理的對象(也就是我們要在方法的前后加上業務邏輯的對象,如例子中的Hello)
14
?????*/
15
????privateObject delegate;
16
17
/**
18
????? * 動態生成方法被處理過后的對象 (寫法固定)
19
????? *
20
????? *@paramdelegate
21
????? *@paramproxy
22
????? *@return
23
?????*/
24
????publicObject bind(Object delegate,Object proxy){
25
????????
26
????????this.proxy=proxy;
27
????????this.delegate=delegate;
28
????????returnProxy.newProxyInstance(
29
????????????????this.delegate.getClass().getClassLoader(),this.delegate
30
???????????????????????? .getClass().getInterfaces(),this);
31
???? }
32
??/**
33
????? * 要處理的對象中的每個方法會被此方法送去JVM調用,也就是說,要處理的對象的方法只能通過此方法調用
34
????? * 此方法是動態的,不是手動調用的
35
?????*/
36
????publicObject invoke(Object proxy, Method method, Object[] args)
37
????????????throwsThrowable{
38
???????? Object result=null;
39
????????try{
40
????????????//反射得到操作者的實例
41
???????????? Class clazz=this.proxy.getClass();
42
????????????//反射得到操作者的Start方法
43
???????????? Method start=clazz.getDeclaredMethod("start",
44
????????????????????newClass[]{ Method.class});
45
????????????//反射執行start方法
46
???????????? start.invoke(this.proxy,newObject[]{ method });
47
????????????//執行要處理對象的原本方法
48
???????????? result=method.invoke(this.delegate, args);
49
//???????????? 反射得到操作者的end方法
50
???????????? Method end=clazz.getDeclaredMethod("end",
51
????????????????????newClass[]{ Method.class});
52
//???????????? 反射執行end方法
53
???????????? end.invoke(this.proxy,newObject[]{ method });
54
55
???????? }catch(Exception e){
56
???????????? e.printStackTrace();
57
???????? }
58
????????returnresult;
59
???? }
60
61
}
62
然后我們把Test.java中的代碼改一下.測試一下:
packagesinosoft.dj.aop.proxyaop;


publicclassTest{

????publicstaticvoidmain(String[] args){
???????? IHello hello=(IHello)newDynaProxyHello().bind(newHello(),newLoggerOperation());
???????? hello.sayGoogBye("Double J");
???????? hello.sayHello("Double J");
????????
???? }
}

結果還是一樣的吧.如果你想在每個方法之前加上日志記錄,而不在方法后加上日志記錄.你就把LoggerOperation類改成如下:1
packagesinosoft.dj.aop.proxyaop;
2
3
importjava.lang.reflect.Method;
4
5
publicclassLoggerOperationimplementsIOperation{
6
7
????publicvoidend(Method method){
8
????????//Logger.logging(Level.DEBUGE, method.getName() + " Method end
.");
9
???? }
10
11
????publicvoidstart(Method method){
12
???????? Logger.logging(Level.INFO, method.getName()+"Method Start!");
13
???? }
14
15
}
16
運行一下.你就會發現,每個方法之后沒有記錄日志了. 這樣,我們就把代理者和操作者解藕了!下面留一個問題給大家,如果我們不想讓所有方法都被日志記錄,我們應該怎么去解藕呢.?我的想法是在代理對象的public Object invoke(Object proxy, Method method, Object[] args)方法里面加上個if(),對傳進來的method的名字進行判斷,判斷的條件存在XML里面.這樣我們就可以配置文件時行解藕了.如果有興趣的朋友可以把操作者,被代理者,都通過配置文件進行配置 ,那么就可以寫一個簡單的SpringAOP框架了.
posted on 2009-07-24 20:43
jadmin 閱讀(95)
評論(0) 編輯 收藏