AOP(面向方面編程)是一種新的編程技術,它能夠將那些本不應該糾纏在一起的任務分離開,從而為程序提供更好的封裝性和互操作性.
AOP是通過代理機制實現的.
代理是指為其他對象提供一種代理以控制對這個對象的訪問.
代理分為三種:
1.靜態代理,代理對象必須實現目標對象的接口,且一個接口只服務于一種類型的目標對象。
2.JDK動態代理,代理對象必須實現java.lang.reflect.InvacationHandler接口,只能為接口創建代理實例。
3.CGLib動態代理,使用非常底層的字節碼技術,可以為任何對象創建代理.
以下是目標對象接口和目標對象.
目標對象接口如下:
package org.test.spring.aop;
public interface IHello
{
public void hello(String name);
}
目標對象如下:
package org.test.spring.aop;
public class HelloSpeaker implements IHello
{
public void hello(String name)
{
System.out.print("Hi," + name);
}
}
一.靜態代理
靜態代理比較容易理解,靜態代理其實很容易理解,靜態代理其實就是個裝飾器而已.
讓代理對象也實現目標對像的接口,這樣做的目的是讓使用者在使用代理對象時感覺不到代理對象的存在.
代理對象如下:
package org.test.spring.aop;
public class HelloSpeakerProxy implements IHello
{
private IHello helloSpeaker;
public HelloSpeakerProxy(IHello helloSpeaker)
{
this.helloSpeaker = helloSpeaker;
}
public void hello(String name)
{
this.helloSpeaker.hello(name);
System.out.println(", welcome to our pub.");
}
public static void main(String[] args)
{
IHello helloSpeaker = new HelloSpeaker();
IHello proxy = new HelloSpeakerProxy(helloSpeaker);
proxy.hello("Huy Vanpon");
}
}
二.JDK動態代理
所謂Dynamic Proxy是這樣一種class:它是在運行時生成的class,在生成它時你必須提供一組interface給它,然后該class就宣稱它實現了這些interface。你當然可以把該class的實例當作這些interface中的任何一個來用。當然啦,這個Dynamic Proxy其實就是一個Proxy,它不會替你作實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。
package org.test.spring.aop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class HelloSpeakerProx implements InvocationHandler
{
private Object target;
public Object invoke(Object proxy, Method method, Object[] parameters)
throws Throwable
{
Object object = null;
try
{
object = method.invoke(target, parameters);
System.out.println(", welcome to our pub.");
}
catch (Exception e)
{
e.printStackTrace();
}
return object;
}
/**
* <p>
* 這個方法用于得到代理對象
* </p>
*
* @param target
* 目標對象
* @return result(Object)代理對象
*/
public Object getProxy(Object target)
{
this.target = target;
/**
* newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
* InvocationHandler invocationHandler) loader: 定義代理類的加加載器(目標類的加載器)
* interfaces: 代理類要實現的接口列表 invocationHandler: 指派方法調用的調用處理程序
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
public static void main(String[] args)
{
IHello proxy = (IHello) new HelloSpeakerProx()
.getProxy(new HelloSpeaker());
proxy.hello("Huy Vanpon");
}
}
三.CGLib動態代理
使用jdk創建代理有一個限制,即它只能為接口創建代理實例.CGLib使用非常底層的字節碼技術,可以為一個類創建子類,并在子類中采用方法攔截的攔截技術,并順勢織入橫切邏輯.
運行這個例子,一定要記得導入CGLib相應的包哦..
package org.test.spring.aop;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class HelloSpeakerPro implements MethodInterceptor


{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz)

{
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object object, Method method, Object[] args,
MethodProxy proxy) throws Throwable

{
Object result = null;
result = proxy.invokeSuper(object, args);
System.out.println(", welcome to our pub.");
return result;
}
public static void main(String[] args)

{
HelloSpeakerPro helloSpeakerPro = new HelloSpeakerPro();
HelloSpeaker helloSpeaker = (HelloSpeaker) helloSpeakerPro
.getProxy(HelloSpeaker.class);
helloSpeaker.hello("Huy Vanpon");
}
}