AOP切面程式設計(動態代理)
面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。
怎麼算是面向切面?在不改變原始碼的情況下嵌入一塊其他的程式碼塊兒。
水平有限也解釋不太好。還是舉例說明。
原來我們有一個介面
public interface StudentInfoService {
void findInfo(String studentName);
}
public class StudentInfoServiceImpl implements StudentInfoService {
@Override
public void findInfo(String studentName) {
System.out.println("你目前輸入的名字是:"+studentName);
}
}
普通呼叫方法,則是
StudentInfoService service = new StudentInfoServiceImpl();//或者我們使用spring注入了一個例項
service.findInfo("hello world");
下面我們有一段程式碼要加入到這個方法前後,但是我們又不想修改findInfo裡的程式碼,在執行方法時執行後加入的程式碼塊。
那麼下面就用到了AOP切面程式設計。
在Spring中aop:config中可以簡單的通過配置加入一些程式碼塊。但這裡不是我們主要討論的。
我們下面是講如何通過程式碼來實現。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyHandler implements InvocationHandler{ //InvocationHandler這個是一定要實現的介面
private Object proxyObj;
public Object bind(Object obj){ //獲取代理物件
this.proxyObj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();//方法之前
Object result=method.invoke(proxyObj,args); //這裡是執行介面方法findInfo
after();//方法之後
return result;
}
public void before() {
System.out.println("-----before-----");
}
public void after() {
System.out.println("-----end-----");
}
}
public class OperaterHander extends MyHandler{
public void before() {//重寫父類的方法
System.out.println("-----OperaterHander before-----");
}
public void after() {
System.out.println("-----OperaterHander end-----");
}
}
public class ProxyTest {
public static void main(String[] args) {
OperaterHander handler = new OperaterHander();
StudentInfoService service = (StudentInfoService) handler.bind(new StudentInfoServiceImpl());
service.findInfo("hello word");
}
}
檢視結果
如此,我們可以不用修改原方法,就可以在方法前後加入自己想要加入的操作。
例如方法前後加日誌,還能實現很好的業務方法隔離。
我想這就是AOP吧。