Spring AOP之動態代理
阿新 • • 發佈:2018-11-14
Spring AOP有兩種動態代理的方式,一種是jdk的動態代理,一種是cglib實現的動態代理,看下兩種代理的實現方式。
1.jdk的動態代理
介面:
public interface ISaler {
public void buy();
}
實現類:
public class CPU implements ISaler{
@Override
public void buy() {
System.out.println("buy cpu");
}
}
代理類:
public class DynamicsAgent implements InvocationHandler { //被代理物件 private Object obj; public DynamicsAgent(Object obj) { this.obj = obj; } //此方法產生一個物件,這個物件可以用來代理被代理的物件,即獲取代理物件 public Object getProxy(){ return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); //執行被代理物件的method方法 Object o = method.invoke(obj, args); after(); return o; } public void before(){ System.out.println("-----brfore---------"); } public void after(){ System.out.println("-----after---------"); } }
測試類:
public class Test {
public static void main(String[] args) {
CPU cpu = new CPU();
DynamicsAgent da = new DynamicsAgent(cpu);
//生成一個代理物件,用被代理物件的介面表示
ISaler p = (ISaler)da.getProxy();
//實際是執行代理類的invoke方法
p.buy();
}
}
執行結果:
-----brfore---------
buy cpu
-----after---------
2.cglib實現:
實現類同上,可以去掉介面:
public class CPU implements ISaler{
@Override
public void buy() {
System.out.println("buy cpu");
}
}
代理類:
public class CGLibProxy implements MethodInterceptor { //被代理物件 private Object obj; public CGLibProxy(Object obj) { this.obj = obj; } //此方法產生一個物件,這個物件可以用來代理被代理的物件,即獲取代理物件 public Object getProxy(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(obj.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy mp) throws Throwable { before(); Object o = mp.invoke(obj, args); after(); return o; } public void before(){ System.out.println("-----brfore---------"); } public void after(){ System.out.println("-----after---------"); } }
測試類:
public class Test {
public static void main(String[] args) {
CPU c = new CPU();
CGLibProxy cp = new CGLibProxy(c);
CPU p = (CPU)cp.getProxy();
//實際是執行代理類的intercept方法
p.buy();
}
}
執行結果:
-----brfore---------
buy cpu
-----after---------
兩種方式的比較:
採用jdk方式來實現動態代理則需要目標類必須實現介面。
採用cglib方式來實現動態類則目標類不能為final型別。
cglib的執行效率更高,但是需要匯入第三方包。