当前位置: 移动技术网 > IT编程>开发语言>Java > java使用动态代理来实现AOP(日志记录)的实例代码

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网