AOP(面向方面)的思想,就是把项目共同的那部分功能分离开来,比如日志记录,避免在业务逻辑里面夹杂着跟业务逻辑无关的代码
id="cproIframe_u1892994_2" width="580" height="90" src="http://pos.baidu.com/acom?adn=3&at=231&aurl=&cad=1&ccd=24&cec=GBK&cfv=17&ch=0&col=zh-CN&conBW=0&conOP=1&cpa=1&dai=2&dis=0&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DZo87x2oY1aTIV7BqAJF2O_rS8vSjZfTOHAVsD7gTOIOVCfKUzurVEwTbWtwjhHQm%26wd%3Daop%25E7%25BC%2596%25E7%25A8%258B%2520java%2520interface%26issp%3D1%26f%3D3%26ie%3Dutf-8%26tn%3Dbaiduhome_pg%26inputT%3D1561%26oq%3DAOP%25E7%25BC%2596%25E7%25A8%258B%2520%26rsp%3D2&ltu=http%3A%2F%2Fwww.jb51.net%2Farticle%2F41733.htm&lu_161=0&lunum=6&n=jb51_cpr&pcs=1196x557&pis=10000x10000&ps=516x133&psr=1366x768&pss=1196x517&qn=339fe513a5488057&rad=&rsi0=580&rsi1=90&rsi5=4&rss0=%23FFFFFF&rss1=%23F7FCFF&rss2=%230000ff&rss3=%23444444&rss4=%23008000&rss5=&rss6=%23e10900&rss7=&scale=&skin=tabcloud_skin_3&stid=5&td_id=1892994&ti=java%E4%BD%BF%E7%94%A8%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E6%9D%A5%E5%AE%9E%E7%8E%B0AOP(%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95)%E7%9A%84%E5%AE%9E%E4%BE%8B%E4%BB%A3%E7%A0%81_java_%E8%84%9A%E6%9C%AC%E4%B9%8B%E5%AE%B6&titFF=%E5%AE%8B%E4%BD%93&titFS=12&titTA=left&tn=text_default_580_90&tpr=1430969112016&ts=1&version=2.0&xuanting=0&dtm=BAIDU_DUP2_SETJSONADSLOT&dc=2&di=u1892994&tt=1430969111986.2132.2227.2228" align="center,center" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true">

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

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

  1. 了解动态代理:Spring AOP基础

    为什么选择AOP: 要了解AOP(面向方面​​的编程),我们需要了解软件开发中的"横切关注点". 在每个项目中,都有一定数量的代码在多个类,多个模块中重复执行,例如几乎所有类和所有 ...

  2. 设计模式总结——代理模式以及java的动态代理

    定义 给目标对象一个代理对象,并由代理对象控制对目标对象的引用.联想到生活中就像是海外代购 既然是代理,就说明他要做的事情要比你直接去做要做的多,这就联系到了方法的增强,也就联系到了AOP,面向切面. ...

  3. 看完Java的动态代理技术——Pythoner笑了

    Java的动态代理常用来包装原始方法调用,用于增强或改写现有方法的逻辑,它在Java技术领域被广为使用,在阿里的Sofa RPC框架序列化中你能看到它的身影,Hibernate的实体类功能增强也是以动 ...

  4. 深入理解Java反射+动态代理,java开发面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起在群里探讨技术. 答: ...

  5. 4种实例 advice aop_JAVA动态代理 和 Spring AOP 4种通知的简单实现

    学习Spring AOP 之前,先要了解下JAVA的动态代理.如果不清楚动态代理的概念就百度一下吧.废话不多说,直接上代码. 我们模拟一个简单的登录 首先我们创建一个用户登录的接口 package c ...

  6. [Java|面试] 面试被问Java的动态代理机制,能说说吗

    Java的动态代理机制 文章目录 Java的动态代理机制 0. 什么是代理 1.动态代理和静态代理的区别 2. 使用代理的情况 3. 动态代理的构成 4. JDK中的动态代理 5. 手写一个JDK动态 ...

  7. 使用动态代理实现用AOP对数据库进行操作

    使用动态代理实现用AOP对数据库进行操作 2008-03-14 11:04 作者:reverocean 来源:赛迪网 [摘要] 要实现对数据库的操作,离不开数据源(DataSource)或者连接(Co ...

  8. java的动态代理机制详解

    2019独角兽企业重金招聘Python工程师标准>>> 参考资料 1.java的动态代理机制详解 转载于:https://my.oschina.net/Howard2016/blog ...

  9. 代理模式及Java实现动态代理

    代理模式 定义:给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象. 代理模式UML图 在上图中: RealSubject 是原对象 ...

最新文章

  1. 20100506 学习记录:grdview添加新的一行数据
  2. 基于SSM实现的民宿网站系统
  3. Spark 1.4连接mysql诡异的问题及解决
  4. java paint文字_Java中paint怎么用
  5. 紫东太初:自动化所开源图-文-音三模态的预训练大模型
  6. php对象怎么拆分字符串数组,在PHP中将字符串拆分为Unicode字符数组的最佳方法是什么?...
  7. 结合随机微分方程,多大Duvenaud团队提出无限深度贝叶斯神经网络
  8. java g1 收集调优_Java性能调优:充分利用垃圾收集器
  9. Python基础入门_5面向对象基础
  10. Axure5.1不能输入中文问题.
  11. Flutter异步编程async与await的基本使用
  12. Chef宣布100%开源,要走红帽模式?\n
  13. loss函数之MultiMarginLoss, MultiLabelMarginLoss
  14. ubuntu14.04中安装open jdk1.8以及报错解决分析
  15. python unittest接口测试_Python+unittest 接口自动化测试
  16. 矢量数据空间索引之R树索引
  17. 2015-5-10分享的PDF
  18. 博士申请 | 上海交通大学自然科学研究院洪亮教授招收深度学习方向博士生
  19. sensor gyro_3d not found
  20. 信号与系统笔记 拉普拉斯变换的性质

热门文章

  1. 【Android 应用开发】 FastJson 使用详解
  2. 4.15第8周 第一节
  3. 使用Filezilla Server配置FTP服务器
  4. Linux下TCP最大连接数受限问题
  5. NOJ——1672剪绳子(博弈)
  6. CentOS 6.5 PYPI本地源制作
  7. 整理记录个人面试问题
  8. SQL语句判断数据库、表、字段是否存在
  9. 今天才发现ff不支持navigate。
  10. main函数的参数详解,它们是何时何处传入的?(main函数的参数值是从操作系统命令行上获得的)