java使用动态代理来实现AOP(日志记录)的实例代码_java

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

首先定义一些业务方法:

复制代码 代码如下:

/**
 * 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";
    }

}

复制代码 代码如下:

/**
 * 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";
    }
}

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

复制代码 代码如下:

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; // 代理目标
    private Object proxy; // 代理对象

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

    private LogInvoHandler() {
    }

    /**
     * 通过Class来生成动态代理对象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); // 执行业务处理

        // 打印日志
        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类测试:

复制代码 代码如下:

/**
 * 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();

    }
}

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

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

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

 

运行结果如下:

九月 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

时间: 2024-11-01 16:40:34

java使用动态代理来实现AOP(日志记录)的实例代码_java的相关文章

java 遍历request中的所有表单数据的实例代码_java

实例如下: Enumeration rnames=request.getParameterNames(); for (Enumeration e = rnames ; e.hasMoreElements() ;) { String thisName=e.nextElement().toString(); String thisValue=request.getParameter(thisName); System.out.println(thisName+"-------"+thisV

Java反射之通过反射获取一个对象的方法信息(实例代码)_java

以下代码为一个工具类 package com.imooc.reflect; import java.lang.reflect.Method; public class ClassUtil { public static void printClassMessage(Object obj){ //要获取类的信息,首先要获取类的类类型 Class c = obj.getClass();//传递的是哪个子类的对象,c就是该子类的类类型 //获取类的名称 System.out.println("类的名称

java 发送带Basic Auth认证的http post请求实例代码_java

构造http header private static final String URL = "url"; private static final String APP_KEY = "key"; private static final String SECRET_KEY = "secret"; /** * 构造Basic Auth认证头信息 * * @return */ private String getHeader() { String

Java生成和解析XML格式文件和字符串的实例代码_java

1.基础知识: Java解析XML一般有四种方法:DOM.SAX.JDOM.DOM4J. 2.使用介绍 1).DOM (1)简介 由W3C(org.w3c.dom)提供的接口,它将整个XML文档读入内存,构建一个DOM树来对各个节点(Node)进行操作.优点就是整个文档都一直在内存中,我们可以随时访问任何节点,并且对树的遍历也是比较熟悉的操作:缺点则是耗内存,并且必须等到所有的文档都读入内存才能进行处理. (2)示例代码: 复制代码 代码如下: <?xml version="1.0&quo

JAVA发送HTTP请求,返回HTTP响应内容,应用及实例代码_java

JDK 中提供了一些对无状态协议请求(HTTP )的支持,下面我就将我所写的一个小例子(组件)进行描述:首先让我们先构建一个请求类(HttpRequester ).该类封装了 JAVA 实现简单请求的代码,如下: 复制代码 代码如下: import java.io.BufferedReader;  import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader;  import

Java 的 FileFilter文件过滤与readline读行操作实例代码_java

复制代码 代码如下: package com.cjonline.foundation.evisa; import java.io.BufferedReader;import java.io.File;import java.io.FileFilter;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;import java.math.BigDecimal; publ

java 反射和动态代理详解及实例代码_java

一.java中的反射 1.通过反射加载类的属性和方法实例代码: /** * java.lang.Class 是反射的源头 * 我们创建了一个类,通过编译(javac.exe)生成对应的class文件,之后我们通过java.exe加载(jvm的类加载器加载)此class文件 * 此class文件加载到内存后,就是一个运行时类,存在缓存区,这个运行时类本事就是一个Class的实例 * 每一个运行时类只加载一次, */ Class<StudentExam> clazz = StudentExam.c

动态代理方式实现AOP

摘要:面向对象的思想强调"一切皆是对象",在面向对象的程序中我们使用真实概念的模型思考问题,使得整个软件系统开发可以像搭建房屋一样有条不紊.然而面向对象也并非完美无缺的,它更注重于对象层次结构方面的东西,对于如何更好的管理对象行为内部结构,还存在着些许不足.那么我们如何使这个问题的得到更完美的解决呢?答案就是AOP. 主要内容: AOP简述 利用动态代理实现AOP 总结 一.AOP简述 AOP的概念早在上个世纪九十年代初就已经出现了,当时的研究人员通过对面向对象思想局限性的分析研究出了

java实现动态代理方法浅析_java

一些Java项目中在mybatis与spring整合中有MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 有鉴于此,本文浅析了java的动态代理. 本文使用动态代理模拟处理事务的拦截器. 接口: public interface UserService { public void addUser(); public void removeUser(); public void searchUser(); } 实现类: public class