自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework
Posted niulity
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework相关的知识,希望对你有一定的参考价值。
MyFramework之AOP部分
原创: 牛超 TOKYO
旨于搭建轻量架构,为目标对象设置装备与拦截器,并利用代理模式封装对象,其中如何拦截对象的方法行为并将装备置于其中尤为关键,具体实现即拦截器类,代码如下所示:
package myFramework;
import java.lang.reflect.* ;
/**
* ProxyObjectHandler : Proxy Object Handler
* create proxy objects according to target object and it's advices
*
* @author Niu Chao
* @since 2008-8-19
* @version 0.1
*/
public class ProxyObjectHandler extends ProxyTargetHandler
{
private IAdvice[] advices ;
private Reflection reflect ;
//construct the proxy according to proxy target and advices
//根据目标 ?象与装备 ?建对 象
public ProxyObjectHandler(Object objproxy , IAdvice[] aAdvs)
{
super(objproxy) ;
reflect = Reflection.getInstance() ;
setAdvices(aAdvs) ;
sortAdvices() ;
}
public Object getProxyObject()
{
return Proxy.newProxyInstance(
this.getObjTarget().getClass().getClassLoader(), this.getObjTarget()
.getClass().getInterfaces(), this);
}
//get the number of advice by sort .
//将装备 按指定方式编 号
private int adviceSortNumber(IAdvice adv)
{
Class cls = adv.getClass() ;
try
{
//IBeforeAdvice
if ( reflect.isAssignable("myFramework.IBeforeAdvice",cls))
{
return 0 ;
}//IAroundAdvice
else if (reflect.isAssignable("myFramework.IAroundAdvice",cls))
{
return 1 ;
}//IThrowsAdvice
else if (reflect.isAssignable("myFramework.IThrowsAdvice",cls))
{
return 2 ;
}
else //Class.forName("myFramework.IAfterAdvice").isAssignableFrom(adv.getClass())
{
return 3 ;
}
}
catch(Exception ex)
{
ex.printStackTrace() ;
System.exit(-1) ;
return -1 ;
}
}
//sort the advices
//以编 号为 ?先级 排序装备
private void sortAdvices()
{
IAdvice advref ;
if (advices.length < 1)
return ;
for ( int i = 0 ; i < advices.length - 1 ; i ++ )
{
for ( int j = i + 1 ; j < advices.length ; j ++)
{
if (adviceSortNumber(advices[i]) > adviceSortNumber(advices[j]))
{
advref = advices[i] ;
advices[i] = advices[j] ;
advices[j] = advref ;
}
}
}
}
//getter
public IAdvice[] getAdvices()
{
return advices ;
}
//setter
public void setAdvices(IAdvice[] advs)
{
advices = advs ;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
// TODO: Add your code here
int i = 0 , j = 0 , iSortnum;
IAdvice advref ;
Reflection reflect = Reflection.getInstance() ;
//arguments of advice
Object[] advArgs ;
Object result = null;
//process advices with before function
//处理带 有前置切入点的装备
for (i = 0 ; i < advices.length ; i ++)
{
iSortnum = adviceSortNumber(advices[i]) ;
if ( iSortnum < 2)
{
//record the start index of aroundadvices
//记 ?AROUND装备 索引号以备 后用
if (iSortnum < 1)
{
j = i ;
}
advArgs = new Object[]{this.getObjTarget() , method , args};
//invoke the function called "before" of device
//调用装备 的前置切入处 理方法
reflect.invokeMethod(advices[i], "before", advArgs) ;
}
else
{
break ;
}
}
//process the proxy with ThrowAdvice set up.
//处理异 常处 理装备
try
{
//process the proxy function
//调用目标 ?象的方法
result = method.invoke(this.getObjTarget(), args);
}
catch(InvocationTargetException ex)
{
boolean bflagthrow = true ;
//catch exception and active thowadvices
for ( ; i < advices.length ; i ++)
{
iSortnum = adviceSortNumber(advices[i]) ;
if (iSortnum == 2) //ThrowAdvice
{
advArgs = new Object[]{this.getObjTarget() , method , args ,ex.getTargetException()};
reflect.invokeMethod(advices[i], "afterThrowing", advArgs) ;
bflagthrow = false ;
}
else
{
break ;
}
}
if (bflagthrow)
{
throw ex.getTargetException();
}
}
//process advices with afterReturn function
//调用各装备 的后置处 理
for (i = j + 1; i < advices.length ; i ++)
{
iSortnum = adviceSortNumber(advices[i]) ;
if (iSortnum != 2)
{
advArgs = new Object[]{this.getObjTarget() , method , args ,result};
reflect.invokeMethod(advices[i], "afterReturn", advArgs) ;
}
}
return result ;
}
}
拦截器通过切入点可以灵活的实现加载装备的所有功能,而装备的定义正是面向方面的体现,各个装备专注于自己的方面比如日志、权限验证等,提高了可重用性。至于装备接口的定义,这里只举一个例子,与Spring不同,IAroundAdvice即对象包围处理装备。
package myFramework;
import java.lang.reflect.Method;
/**
* IAroundAdvice : Around Advice Interface
* handle a method and process before/after(around) it.
* @author Niu Chao
* @since 2008-8-19
* @version 0.1
*/
public interface IAroundAdvice extends IAdvice
{
public void before(Object target, Method m, Object[] args) ;
public void afterReturn(Object target, Method m, Object[] args,
Object objReturn);
}
正如定义的那样,该装备的实例对象必须实现两个函数before与afterReturn。恰似结合了BEFORE与AFTER两种装备那样。这 以上是关于自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework的主要内容,如果未能解决你的问题,请参考以下文章 自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework 自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework