自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework(3)
2008-09-17 12:42
726 查看
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和代理模式实现了松散耦合,并且分工明确,系统开发也会变得更为自自由由。
原创: 牛超 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和代理模式实现了松散耦合,并且分工明确,系统开发也会变得更为自自由由。
相关文章推荐
- 自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework(1)
- 自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework(4)
- 自行打造实现控制反转容器(IOC)与面向方面编程(AOP)的轻量级Framework(2)
- idea 实现Spring讲解(Ioc-控制反转)/Aop(面向切面的编程)
- SPRING--Spring中IOC(反转控制) 和 AOP(面向方面编程)
- 为什么说Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架?
- 笔记——spring基本使用(控制反转IOC、面向切面编程AOP、声明式事务)
- Java+spring切面编程(aop)spring控制反转(ioc)+hibenrate对象关系映射(ORM
- 实现MVC+AOP面向方面编程
- Spring基础、IOC(控制反转)、AOP(面向切面编程)、Log4j、注解配置
- Spring.Net学习 控制反转(IoC)和面向切面编程(AOP) (转)
- [.net 面向对象程序设计深入](31)实战设计模式——使用Ioc模式(控制反转或依赖注入)实现松散耦合设计(1)
- POJO编程模型、轻量级容器和控制反转
- Spring基础、IOC(控制反转)、AOP(面向切面编程)、Log4j、注解配置
- Spring 之 控制反转(IoC), 依赖注入(DI)和面向切面(AOP)
- Spring.Net学习 控制反转(IoC)和面向切面编程(AOP)
- spring的IOC(控制反转)与AOP(面向切面编程)
- java+spring切面编程(aop)spring控制反转(ioc)+hibenrate对象关系映射(ORM) 学习网址
- IoC容器与面向方面编程在SP无线运营系统设计中的应用