1. 程式人生 > >Spring AOP之動態代理

Spring AOP之動態代理

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的執行效率更高,但是需要匯入第三方包。