java使用動態代理來實現AOP

來源:文萃谷 2.81W

下面是一個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

熱門標籤