欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-18 15:54:46
下面是一个aop实现的简单例子: 首先定义一些业务方法: 复制代码 代码如下:/** * created with intellij idea. ...

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

上一篇:

下一篇: