好長時間沒有用過Spring了. 突然拿起書.我都發現自己對AOP都不熟悉了.
其實AOP的意思就是面向切面編程.
OO注重的是我們解決問題的方法(封裝成Method),而AOP注重的是許多解決解決問題的方法中的共同點,是對OO思想的一種補充!
還是拿人家經常舉的一個例子講解一下吧:
比如說,我們現在要開發的一個應用裏面有很多的業務方法,但是,我們現在要對這個方法的執行做全面監控,或部分監控.也許我們就會在要一些方法前去加上一條日誌記錄,
我們寫個例子看看我們最簡單的解決方案
我們先寫一個接口IHello.java代碼如下:
其實AOP的意思就是面向切面編程.
OO注重的是我們解決問題的方法(封裝成Method),而AOP注重的是許多解決解決問題的方法中的共同點,是對OO思想的一種補充!
還是拿人家經常舉的一個例子講解一下吧:
比如說,我們現在要開發的一個應用裏面有很多的業務方法,但是,我們現在要對這個方法的執行做全面監控,或部分監控.也許我們就會在要一些方法前去加上一條日誌記錄,
我們寫個例子看看我們最簡單的解決方案
我們先寫一個接口IHello.java代碼如下:
1package sinosoft.dj.aop.staticaop;
2
3public interface IHello {
4 /**
5 * 假設這是一個業務方法
6 * @param name
7 */
8 void sayHello(String name);
9}
10
2
3public interface IHello {
4 /**
5 * 假設這是一個業務方法
6 * @param name
7 */
8 void sayHello(String name);
9}
10
裏面有個方法,用於輸入"Hello" 加傳進來的姓名;我們去寫個類實現IHello接口
package sinosoft.dj.aop.staticaop;
public class Hello implements IHello {
public void sayHello(String name) {
System.out.println("Hello " + name);
}
}
public class Hello implements IHello {
public void sayHello(String name) {
System.out.println("Hello " + name);
}
}
現在我們要爲這個業務方法加上日誌記錄的業務,我們在不改變原代碼的情況下,我們會去怎麼做呢?也許,你會去寫一個類去實現IHello接口,並依賴Hello這個類.代碼如下:
1package sinosoft.dj.aop.staticaop;
2
3public class HelloProxy implements IHello {
4 private IHello hello;
5
6 public HelloProxy(IHello hello) {
7 this.hello = hello;
8 }
9
10 public void sayHello(String name) {
11 Logger.logging(Level.DEBUGE, "sayHello method start.");
12 hello.sayHello(name);
13 Logger.logging(Level.INFO, "sayHello method end!");
14
15 }
16
17}
18
2
3public class HelloProxy implements IHello {
4 private IHello hello;
5
6 public HelloProxy(IHello hello) {
7 this.hello = hello;
8 }
9
10 public void sayHello(String name) {
11 Logger.logging(Level.DEBUGE, "sayHello method start.");
12 hello.sayHello(name);
13 Logger.logging(Level.INFO, "sayHello method end!");
14
15 }
16
17}
18
其中.Logger類和Level枚舉代碼如下:
Logger.java
1package sinosoft.dj.aop.staticaop;
2
3import java.util.Date;
4
5public class Logger{
6 /**
7 * 根據等級記錄日誌
8 * @param level
9 * @param context
10 */
11 public static void logging(Level level, String context) {
12 if (level.equals(Level.INFO)) {
13 System.out.println(new Date().toLocaleString() + " " + context);
14 }
15 if (level.equals(Level.DEBUGE)) {
16 System.err.println(new Date() + " " + context);
17 }
18 }
19
20}
21
2
3import java.util.Date;
4
5public class Logger{
6 /**
7 * 根據等級記錄日誌
8 * @param level
9 * @param context
10 */
11 public static void logging(Level level, String context) {
12 if (level.equals(Level.INFO)) {
13 System.out.println(new Date().toLocaleString() + " " + context);
14 }
15 if (level.equals(Level.DEBUGE)) {
16 System.err.println(new Date() + " " + context);
17 }
18 }
19
20}
21
Level.java
1package sinosoft.dj.aop.staticaop;
2
3public enum Level {
4 INFO,DEBUGE;
5}
6
2
3public enum Level {
4 INFO,DEBUGE;
5}
6
那我們去寫個測試類看看,代碼如下:
Test.java
從上面的代碼我們可以看出,hello對象是被HelloProxy這個所謂的代理態所創建的.這樣,如果我們以後要把日誌記錄的功能去掉.那我們只要把得到hello對象的代碼改成以下:
上面代碼,可以說是AOP最簡單的實現!
但是我們會發現一個問題,如果我們像Hello這樣的類很多,那麼,我們是不是要去寫很多個HelloProxy這樣的類呢.沒錯,是的.其實也是一種很麻煩的事.在jdk1.3以後.jdk跟我們提供了一個API java.lang.reflect.InvocationHandler的類. 這個類可以讓我們在JVM調用某個類的方法時動態的爲些方法做些什麼事.讓我們把以上的代碼改一下來看看效果.
同樣,我們寫一個IHello的接口和一個Hello的實現類.在接口中.我們定義兩個方法;代碼如下 :
IHello.java
Hello.java
我們一樣的去寫一個代理類.只不過.讓這個類去實現java.lang.reflect.InvocationHandler接口,代碼如下:
見附件...
Test.java
1package sinosoft.dj.aop.staticaop;
2
3public class Test {
4 public static void main(String[] args) {
5 IHello hello = new HelloProxy(new Hello());
6 hello.sayHello("Doublej");
7 }
8}
9
運行以上代碼我們可以得到下面結果:2
3public class Test {
4 public static void main(String[] args) {
5 IHello hello = new HelloProxy(new Hello());
6 hello.sayHello("Doublej");
7 }
8}
9
Tue Mar 04 20:57:12 CST 2008 sayHello method start.
Hello Doublej
2008-3-4 20:57:12 sayHello method end!
Hello Doublej
2008-3-4 20:57:12 sayHello method end!
從上面的代碼我們可以看出,hello對象是被HelloProxy這個所謂的代理態所創建的.這樣,如果我們以後要把日誌記錄的功能去掉.那我們只要把得到hello對象的代碼改成以下:
1package sinosoft.dj.aop.staticaop;
2
3public class Test {
4 public static void main(String[] args) {
5 IHello hello = new Hello();
6 hello.sayHello("Doublej");
7 }
8}
9
2
3public class Test {
4 public static void main(String[] args) {
5 IHello hello = new Hello();
6 hello.sayHello("Doublej");
7 }
8}
9
上面代碼,可以說是AOP最簡單的實現!
但是我們會發現一個問題,如果我們像Hello這樣的類很多,那麼,我們是不是要去寫很多個HelloProxy這樣的類呢.沒錯,是的.其實也是一種很麻煩的事.在jdk1.3以後.jdk跟我們提供了一個API java.lang.reflect.InvocationHandler的類. 這個類可以讓我們在JVM調用某個類的方法時動態的爲些方法做些什麼事.讓我們把以上的代碼改一下來看看效果.
同樣,我們寫一個IHello的接口和一個Hello的實現類.在接口中.我們定義兩個方法;代碼如下 :
IHello.java
1package sinosoft.dj.aop.proxyaop;
2
3public 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
2
3public 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
1package sinosoft.dj.aop.proxyaop;
2
3public 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
2
3public 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接口,代碼如下:
見附件...