配色: 字号:
java使用动态代理来实现AOP(日志记录)的实例代码
2016-12-20 | 阅:  转:  |  分享 
  
java使用动态代理来实现AOP(日志记录)的实例代码



AOP(面向方面)的思想,就是把项目共同的那部分功能分离开来,比如日志记录,避免在业务逻辑里面夹杂着跟业务逻辑无关的代码



下面是一个AOP实现的简单例子:



首先定义一些业务方法:





复制代码代码如下:





/

CreatedwithIntelliJIDEA.

Author:wangjieemail:tiantian.china.2@gmail.com

Date:13-9-23

Time:下午3:49

/

publicinterfaceBussinessService{

publicStringlogin(Stringusername,Stringpassword);

publicStringfind();

}



publicclassBussinessServiceImplimplementsBussinessService{

privateLoggerlogger=Logger.getLogger(this.getClass().getSimpleName());



@Override

publicStringlogin(Stringusername,Stringpassword){

return"loginsuccess";

}



@Override

publicStringfind(){

return"findsuccess";

}



}







复制代码代码如下:





/

CreatedwithIntelliJIDEA.

Author:wangjieemail:tiantian.china.2@gmail.com

Date:13-9-24

Time:上午10:27

/

publicinterfaceWorkService{

publicStringwork();

publicStringsleep();

}



publicclassWorkServiceImplimplementsWorkService{

@Override

publicStringwork(){

return"worksuccess";

}



@Override

publicStringsleep(){

return"sleepsuccess";

}

}





实现InvocationHandler接口,使用map来存储不同的InvocationHandler对象,避免生成过多。





复制代码代码如下:





packagecom.wangjie.aoptest2.invohandler;



importjava.lang.reflect.InvocationHandler;

importjava.lang.reflect.Method;

importjava.lang.reflect.Proxy;

importjava.util.Arrays;

importjava.util.HashMap;

importjava.util.logging.Logger;



/

CreatedwithIntelliJIDEA.

Author:wangjieemail:tiantian.www.visa158.comchina.2@gmail.com

Date:13-9-23

Time:下午3:47

/

publicclassLogInvoHandlerimplementsInvocationHandler{

privateLoggerlogger=Logger.getLogger(this.getClass().getSimpleName());



privateObjecttarget;//代理目标

privateObjectproxy;//代理对象



privatestaticHashMap,LogInvoHandler>invoHandlers=newHashMap,LogInvoHandler>();



privateLogInvoHandler(){

}



/

通过Class来生成动态代理对象Proxy

@paramclazz

@return

/

publicsynchronizedstaticTgetProxyInstance(Classclazz){

LogInvoHandlerinvoHandler=invoHandlers.get(clazz);



if(null==invoHandler){

invoHandler=newLogInvoHandler();

try{

Ttar=clazz.newInstance();

invoHandler.setTarget(tar);

invoHandler.setProxy(Proxy.newProxyInstance(tar.getClass().getClassLoader(),

tar.getClass().getInterfaces(),invoHandler));

}catch(Exceptione){

e.printStackTrace();

}

invoHandlers.put(clazz,invoHandler);



}



return(T)invoHandler.getProxy();

}



@Override

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{



Objectresult=method.invoke(target,args);//执行业务处理



//打印日志

logger.info("____invokemethod:"+method.getName()

+";args:"+(null==args?"null":Arrays.asList(args).toString())

+";return:"+result);





returnresult;

}



publicObjectgetTarget(){

returntarget;

}



publicvoidsetTarget(Objecttarget){

this.target=target;

}



publicObjectgetProxy(){

returnproxy;

}



publicvoidsetProxy(Objectproxy){

this.proxy=proxy;

}

}





然后编写一个Test类测试:





复制代码代码如下:





/

CreatedwithIntelliJIDEA.

Author:wangjieemail:tiantian.china.2@gmail.com

Date:13-9-24

Time:上午9:54

/

publicclassTest{

publicstaticLoggerlogger=Logger.getLogger(Test.class.getwww.hunanwang.netSimpleName());

publicstaticvoidmain(String[]args){



BussinessServicebs=LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);

bs.login("zhangsan","123456");

bs.find();



logger.info("--------------------------------------");



WorkServicews=LogInvoHandler.getProxyInstance(WorkServiceImpl.class);

ws.work();

ws.sleep();



logger.info("--------------------------------------");



BussinessServicebss=LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);

bss.login("lisi","654321");

bss.find();



}

}





以后需要添加新的业务逻辑XXXService,只需要调用



XXXServicexs=LogInvoHandler.getProxyInstance(XXXServiceImpl.class);



即可。



也可以模仿Spring等框架的配置,把bean的类名配置在xml文件中,如:







然后在java代码中解析xml,通过Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl");获得Class对象



然后通过LogInvoHandler.getProxyInstance(Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl"));获得代理对象Proxy



再使用反射去调用代理对象的方法。



运行结果如下:



九月24,201311:08:03上午com.wangjie.aoptest2.invohandler.LogInvoHandlerinvoke

INFO:____invokemethod:login;args:[zhangsan,123456];return:loginsuccess

九月24,201311:08:03上午com.wangjie.aoptest2.invohandler.LogInvoHandlerinvoke

INFO:____invokemethod:find;args:null;return:findsuccess

九月24,201311:08:03上午com.wangjie.aoptest2.Testmain

INFO:--------------------------------------

九月24,201311:08:03上午com.wangjie.aoptest2.invohandler.LogInvoHandlerinvoke

INFO:____invokemethod:work;args:null;return:worksuccess

九月24,201311:08:03上午com.wangjie.aoptest2.invohandler.LogInvoHandlerinvoke

INFO:____invokemethod:sleep;args:null;return:sleepsuccess

九月24,201311:08:03上午com.wangjie.aoptest2.Testmain

INFO:--------------------------------------

九月24,201311:08:03上午com.wangjie.aoptest2.invohandler.LogInvoHandlerinvoke

INFO:____invokemethod:login;args:[lisi,654321];return:loginsuccess

九月24,201311:08:03上午com.wangjie.aoptest2.invohandler.LogInvoHandlerinvoke

INFO:____invokemethod:find;args:null;return:findsuccess





















献花(0)
+1
(本文系白狐一梦首藏)