Aop實(shí)現(xiàn)原理:攔截器+動(dòng)態(tài)代理
Aop要做的事情:在真正的對(duì)象代碼執(zhí)行之前,做點(diǎn)什么,執(zhí)行完之后,再做點(diǎn)什么,廢話不多說(shuō),直接從代碼開(kāi)始講起
ProxyBean的現(xiàn)實(shí):
-
第一步:動(dòng)態(tài)代理
- JDK提供了·類Proxy:包含newProxyInstance方法
public statistic Object newProxyInstance(ClassLoader classLoadeer,Class<?>[] interface,InvocationHandler invocationHangler);//生成一個(gè)代理對(duì)象
ClassLoader:類加載器
interfaces:綁定的接口,也就是把代理對(duì)象綁定到哪些接口下,可以是多個(gè)
invocationhandler:綁定代理對(duì)象邏輯實(shí)現(xiàn)
invocationHandler對(duì)象定義了一個(gè)invoke方法:
public Object invoke(Object proxy,Method method,Object[] args){
System.out.println("進(jìn)入代理邏輯方法");
System.out.println("在調(diào)度真實(shí)對(duì)象之前的服務(wù)");
Object obj=method.invoke(target,args);//通過(guò)反射實(shí)現(xiàn),調(diào)度真實(shí)對(duì)象
}
補(bǔ)充: JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意方法和屬性;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為java語(yǔ)言的反射機(jī)制。 詳情見(jiàn) http://www.itdecent.cn/p/9be58ee20dee
-
第二部分?jǐn)r截器:
1 Intercepter:攔截器接口
public interface Intercepter{
//事前方法
public boolean before();
//事后方法
public void after();
/**
*取代原有事情方法
* @param invocation --回調(diào)參數(shù),可以通過(guò)它的proceed方法,回調(diào)原有事件
* @return 原有事件返回對(duì)象
*/
public Object arround(Invocation invocation);
//是否返回方法,事件沒(méi)有異常時(shí)執(zhí)行
public void afterReturning();
//時(shí)候異常方法,事件異常時(shí)執(zhí)行
public void afterThrowing();
//是否使用around取代原有方法
boolean useAround();
}
2 invocation
public class invocation{
private Object[] param ;
private Method method;
private Object target;
public Invocation(Object[] param,Method method,Object target){
.....//構(gòu)造函數(shù)
}
//反射方法
public Object proceed() Throws Exception{
return method.invoke(target,param);//以反射的形式去調(diào)用原有的方法
}
}
3 ProxyBean
Public class ProxyBean implement InvocationHandler{
private Object target;//被代理對(duì)象
private Interceptor interceptor=null;//攔截器
//生成一個(gè)代理對(duì)象
public statistic Object getProxyBean(Obeject targer,Interceptor interceptor){
ProxyBean proxyBean=new ProxyBean();
proxyBean.target=target;
proxyBean.interceptor=interceptor;
//生成代理對(duì)象
Object proxy=Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),proxyBean);
return proxy
}
//處理代理對(duì)象方法邏輯
@Override
public Object invoke(Object proxy,Method method,Object[] args){
//異常標(biāo)志
boolean exceptionFlag=false;
Invocation invocation=new Invocation(target,method,args);
Object retobj=null;
try{
if(this.intercepter.before()){
retobj=this.interceptor.aroud(invocation);
}else{
retObj=method.invoke(target,args);
}
}catch(Exception e){
exceptionFlag=true;
}
this.interceptor.after();
if(exceptionFlag){
this.interceptor.afterThrowing();
}else{
this.interceptor.afterReturning();
return retObj;
}
return null;
}
}
-
說(shuō)明:
- 利用newProxyInstance()生成一個(gè)與被代理對(duì)象綁定了的代理對(duì)象
- 實(shí)現(xiàn)InvocationHandler的invoke方法
AOP:以上就是AOP的原理,一種約定流程的編程,將代碼切開(kāi),植入一些我們需要的處理。比如我們可以攔截所有的業(yè)務(wù)代碼,將他們統(tǒng)一的非業(yè)務(wù)切割出來(lái),讓代理去實(shí)現(xiàn),這樣開(kāi)發(fā)者就可以專心于業(yè)務(wù)代碼,其他的雜事都讓代理去處理了。