當前位置:才華齋>計算機>java語言>

java使用動態代理來實現AOP

java語言 閱讀(2.89W)

下面是一個AOP實現的簡單例子:

java使用動態代理來實現AOP

首先定義一些業務方法:

複製程式碼 程式碼如下:

/**

* Created with IntelliJ IDEA.

* Author: wangjie

* Date: 13-9-23

* Time: 下午3:49

*/

public interface BussinessService {

public String login(String username, String password);

public String find();

}

public class BussinessServiceImpl implements BussinessService {

private Logger logger = ogger(lass()impleName());

@Override

public String login(String username, String password) {

return "login success";

}

@Override

public String find() {

return "find success";

}

}

複製程式碼 程式碼如下:

/**

* Created with IntelliJ IDEA.

* Author: wangjie

* Date: 13-9-24

* Time: 上午10:27

*/

public interface WorkService {

public String work();

public String sleep();

}

public class WorkServiceImpl implements WorkService{

@Override

public String work() {

return "work success";

}

@Override

public String sleep() {

return "sleep success";

}

}

實現InvocationHandler介面,使用map來儲存不同的cationHandler物件,避免生成過多。

複製程式碼 程式碼如下:

package handler;

import cationHandler;

import od;

import y;

import ys;

import Map;

import er;

/**

* Created with IntelliJ IDEA.

* Author: wangjie

* Date: 13-9-23

* Time: 下午3:47

*/

public class LogInvoHandler implements InvocationHandler{

private Logger logger = ogger(lass()impleName());

private Object target; // 代理目標

private Object proxy; // 代理物件

private static HashMap<Class, LogInvoHandler> invoHandlers = new HashMap<Class, LogInvoHandler>();

private LogInvoHandler() {

}

/**

* 通過Class來生成動態代理物件Proxy

* @param clazz

* @return

*/

public synchronized staticT getProxyInstance(Classclazz){

LogInvoHandler invoHandler = (clazz);

if(null == invoHandler){

invoHandler = new LogInvoHandler();

try {

T tar = nstance();

arget(tar);

roxy(roxyInstance(lass()lassLoader(),

lass()nterfaces(), invoHandler));

} catch (Exception e) {

tStackTrace();

}

(clazz, invoHandler);

}

return (T)roxy();

}

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

Object result = ke(target, args); // 執行業務處理

// 列印日誌

("____invoke method: " + ame()

+ "; args: " + (null == args ? "null" : st(args)ring())

+ "; return: " + result);

return result;

}

public Object getTarget() {

return target;

}

public void setTarget(Object target) {

et = target;

}

public Object getProxy() {

return proxy;

}

public void setProxy(Object proxy) {

y = proxy;

}

}

然後編寫一個Test類測試:

複製程式碼 程式碼如下:

/**

* Created with IntelliJ IDEA.

* Author: wangjie

* Date: 13-9-24

* Time: 上午9:54

*/

public class Test {

public static Logger logger = ogger(impleName());

public static void main(String[] args) {

BussinessService bs = roxyInstance(s);

n("zhangsan", "123456");

();

("--------------------------------------");

WorkService ws = roxyInstance(s);

();

p();

("--------------------------------------");

BussinessService bss = roxyInstance(s);

n("lisi", "654321");

();

}

}

以後需要新增新的業務邏輯XXXService,只需要呼叫

XXXService xs = roxyInstance(s);

即可。

也可以模仿Spring等框架的配置,把bean的類名配置在xml檔案中,如:

然後在java程式碼中解析xml,通過ame("inessServiceImpl");獲得Class物件

然後通過roxyInstance(ame("inessServiceImpl"));獲得代理物件Proxy

再使用反射去呼叫代理物件的方法。

執行結果如下:

九月 24, 2013 11:08:03 上午 nvoHandler invoke

INFO: ____invoke method: login; args: [zhangsan, 123456]; return: login success

九月 24, 2013 11:08:03 上午 nvoHandler invoke

INFO: ____invoke method: find; args: null; return: find success

九月 24, 2013 11:08:03 上午 main

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

九月 24, 2013 11:08:03 上午 nvoHandler invoke

INFO: ____invoke method: work; args: null; return: work success

九月 24, 2013 11:08:03 上午 nvoHandler invoke

INFO: ____invoke method: sleep; args: null; return: sleep success

九月 24, 2013 11:08:03 上午 main

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

九月 24, 2013 11:08:03 上午 nvoHandler invoke

INFO: ____invoke method: login; args: [lisi, 654321]; return: login success

九月 24, 2013 11:08:03 上午 nvoHandler invoke

INFO: ____invoke method: find; args: null; return: find success