java使用动态代理来实现AOP(日志记录)的实例代码
下面是一個AOP實現(xiàn)的簡單例子:
首先定義一些業(yè)務(wù)方法:
復(fù)制代碼代碼如下:
/**
?* Created with IntelliJ IDEA.
?* Author: wangjie? email:tiantian.china.2@gmail.com
?* 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 = Logger.getLogger(this.getClass().getSimpleName());
??? @Override
??? public String login(String username, String password) {
??????? return "login success";
??? }
??? @Override
??? public String find() {
??????? return "find success";
??? }
}
復(fù)制代碼代碼如下:
/**
?* Created with IntelliJ IDEA.
?* Author: wangjie? email:tiantian.china.2@gmail.com
?* 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";
??? }
}
實現(xiàn)InvocationHandler接口,使用map來存儲不同的InvocationHandler對象,避免生成過多。
復(fù)制代碼代碼如下:
package com.wangjie.aoptest2.invohandler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.logging.Logger;
/**
?* Created with IntelliJ IDEA.
?* Author: wangjie? email:tiantian.china.2@gmail.com
?* Date: 13-9-23
?* Time: 下午3:47
?*/
public class LogInvoHandler implements InvocationHandler{
??? private Logger logger = Logger.getLogger(this.getClass().getSimpleName());
??? private Object target; // 代理目標(biāo)
??? private Object proxy; // 代理對象
??? private static HashMap<Class<?>, LogInvoHandler> invoHandlers = new HashMap<Class<?>, LogInvoHandler>();
??? private LogInvoHandler() {
??? }
??? /**
???? * 通過Class來生成動態(tài)代理對象Proxy
???? * @param clazz
???? * @return
???? */
??? public synchronized static<T> T getProxyInstance(Class<T> clazz){
??????? LogInvoHandler invoHandler = invoHandlers.get(clazz);
??????? if(null == invoHandler){
??????????? invoHandler = new LogInvoHandler();
??????????? try {
??????????????? T tar = clazz.newInstance();
??????????????? invoHandler.setTarget(tar);
??????????????? invoHandler.setProxy(Proxy.newProxyInstance(tar.getClass().getClassLoader(),
??????????????????????? tar.getClass().getInterfaces(), invoHandler));
??????????? } catch (Exception e) {
??????????????? e.printStackTrace();
??????????? }
??????????? invoHandlers.put(clazz, invoHandler);
??????? }
??????? return (T)invoHandler.getProxy();
??? }
??? @Override
??? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
??????? Object result = method.invoke(target, args); // 執(zhí)行業(yè)務(wù)處理
??????? // 打印日志
??????? logger.info("____invoke method: " + method.getName()
??????????????????? + "; args: " + (null == args ? "null" : Arrays.asList(args).toString())
??????????????????? + "; return: " + result);
??????? return result;
??? }
??? public Object getTarget() {
??????? return target;
??? }
??? public void setTarget(Object target) {
??????? this.target = target;
??? }
??? public Object getProxy() {
??????? return proxy;
??? }
??? public void setProxy(Object proxy) {
??????? this.proxy = proxy;
??? }
}
然后編寫一個Test類測試:
復(fù)制代碼代碼如下:
/**
?* Created with IntelliJ IDEA.
?* Author: wangjie? email:tiantian.china.2@gmail.com
?* Date: 13-9-24
?* Time: 上午9:54
?*/
public class Test {
??? public static Logger logger = Logger.getLogger(Test.class.getSimpleName());
??? public static void main(String[] args) {
??????? BussinessService bs = LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
??????? bs.login("zhangsan", "123456");
??????? bs.find();
??????? logger.info("--------------------------------------");
??????? WorkService ws = LogInvoHandler.getProxyInstance(WorkServiceImpl.class);
??????? ws.work();
??????? ws.sleep();
??????? logger.info("--------------------------------------");
??????? BussinessService bss = LogInvoHandler.getProxyInstance(BussinessServiceImpl.class);
??????? bss.login("lisi", "654321");
??????? bss.find();
??? }
}
以后需要添加新的業(yè)務(wù)邏輯XXXService,只需要調(diào)用
XXXService xs = LogInvoHandler.getProxyInstance(XXXServiceImpl.class);
即可。
也可以模仿Spring等框架的配置,把bean的類名配置在xml文件中,如:
<bean id="bussinessService" class="com.wangjie.aoptest2.service.impl.BussinessServiceImpl">
然后在java代碼中解析xml,通過Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl");獲得Class對象
然后通過LogInvoHandler.getProxyInstance(Class.forName("com.wangjie.aoptest2.service.impl.BussinessServiceImpl"));獲得代理對象Proxy
再使用反射去調(diào)用代理對象的方法。
?
運行結(jié)果如下:
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: login; args: [zhangsan, 123456]; return: login success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: find; args: null; return: find success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.Test main
INFO: --------------------------------------
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: work; args: null; return: work success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: sleep; args: null; return: sleep success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.Test main
INFO: --------------------------------------
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: login; args: [lisi, 654321]; return: login success
九月 24, 2013 11:08:03 上午 com.wangjie.aoptest2.invohandler.LogInvoHandler invoke
INFO: ____invoke method: find; args: null; return: find success
總結(jié)
以上是生活随笔為你收集整理的java使用动态代理来实现AOP(日志记录)的实例代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AOP的两种实现方式
- 下一篇: 23种设计模式及其对应实例-转