AOP就是Spring面向切面程式設計,經常會在調用某一個方法前或者調用以後去執行其他的操作,這就需要用到AOP原理了
AOP是怎麼做到切面點切入的呢,就是通過動态代理來實作的,動态代理目前主要有JDK的動态代理(InvocationHandler)和Cglib兩種
首先,最早接觸到的代理應該是設計模式中的代理模式,是靜态代理,主要是有接口類,接口實作類和代理類,代碼如下

代碼如下:
接口類
package test;
public interface Caculate {
public int add(int a,int b);
public int sub(int a,int b);
}
接口實作類
package test;
public class AddCaculate implements Caculate{
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return a+b;
}
@Override
public int sub(int a, int b) {
// TODO Auto-generated method stub
return a-b;
}
}
代理類
package test;
public class CaculateProxy implements Caculate{
private Caculate caculate;
public CaculateProxy(Caculate caculate) {
this.caculate=caculate;
// TODO Auto-generated constructor stub
}
@Override
public int add(int a, int b) {
// TODO Auto-generated method stub
return caculate.add(a, b);
}
@Override
public int sub(int a, int b) {
// TODO Auto-generated method stub
return caculate.add(a, b);
}
}
測試
AddCaculate addCaculate = new AddCaculate();
CaculateProxy proxy = new CaculateProxy(addCaculate);
proxy.add(1, 2);
proxy.sub(2, 1);
這裡就是靜态代理類的實作,那麼問題來了,如果需要增添或者删除一些方法,那麼代理類也要跟随着做相應的修改,此時就需要動态代理來解決這個問題了,那麼動态代理是啥原理實作的呢,看下面一張圖

這是java代碼在jvm裡邊編譯解析程子節碼的過程,Java的源代碼.java檔案通過編譯器編譯成.class檔案後,jvm就在加載類的時候,會根據.class的組織結構,生成對應的位元組碼 再進行加載類,這就實作了.class在運作期間才被确定,就成就了動态代理了
1.InvocationHandler模式
InvocationHandler就是在靜态代理模式上引入了InvocationHandler類,這個類就是負責在運作時候,動态調用proxy所要調用的對應實作類的方法,代碼如下
接口類和實作類還是和靜态代理一樣
代理類如下,實作了InvocationHandler:
package test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class CaculateProxy implements InvocationHandler{
private Object caculate;
public CaculateProxy(Object caculate) {
this.caculate=caculate;
// TODO Auto-generated constructor stub
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
method.invoke(caculate, args);
return null;
}
}
測試類
AddCaculate addCaculate = new AddCaculate();
InvocationHandler invocationHandler = new CaculateProxy(addCaculate);
Caculate caculate = (Caculate) Proxy.newProxyInstance(addCaculate.getClass().getClassLoader(),
addCaculate.getClass().getInterfaces(), invocationHandler);
caculate.add(2, 3);
caculate.sub(1, 2);
我們看到addCaculate.getClass(),這段代碼實際上我們是把實作類中的接口資訊與觸發器invocationHandler綁定,也就是說如果實作類有接口中沒有的方法是不能被代理的。總的來說,JDK這種代理1)要保證有接口,2)不能代理接口中沒有的方法
為避免上面的兩種缺陷,這就是要說的另一種動态代理實作方式,那就是代理類繼承被代理類,不需要接口,這種實作如 Cglib,Cglib是實作了MethodInterceptor攔截器
它的流程是這樣的:
1).查找A上的所有非final 的public類型的方法定義;
2).将這些方法的定義轉換成位元組碼;
3).将組成的位元組碼轉換成相應的代理的class對象;
4).實作 MethodInterceptor接口,用來處理 對代理類上所有方法的請求(這個接口和JDK動态代理InvocationHandler的功能和角色是一樣的
本文參考文章:http://blog.csdn.net/luanlouis/article/details/24589193