欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 宝鼎售后问题提交 | 后台管理


新闻资讯

MENU

软件开发知识

我要在调用insert()与 图纸加密 update()方法前后分别打印时间

点击: 次  来源:宝鼎软件 时间:2017-10-15

原文出处: 五月的仓颉

媒介

一年半前写了一篇文章Spring3:AOP,是其时进修如何利用Spring AOP的时候写的,较量基本。这篇文章最后的推荐以及回覆认为我写的对各人有辅佐的评论有许多,可是此刻从我小我私家的角度来看,这篇文章写得并欠好,甚至可以说是没有太多实质性的内容,因此这些推荐和评论让我以为受之有愧。

基于以上原因,更新一篇文章,从最基本的原始代码–>利用设计模式(装饰器模式与署理)–>利用AOP三个条理来讲授一下为什么我们要利用AOP,但愿这篇文章可以对网友伴侣们有益。

原始代码的写法

既然要通过代码来演示,那必需要有例子,这里我的例子为:

有一个接口Dao有insert、delete、update三个要领,在insert与update被挪用的前后,打印挪用前的毫秒数与挪用后的毫秒数

首先界说一个Dao接口:

/**
 * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
 */
public interface Dao {

    public void insert();
    
    public void delete();
    
    public void update();
    
}

然后界说一个实现类DaoImpl:

/**
 * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
 */
public class DaoImpl implements Dao {

    @Override
    public void insert() {
        System.out.println("DaoImpl.insert()");
    }

    @Override
    public void delete() {
        System.out.println("DaoImpl.delete()");
    }

    @Override
    public void update() {
        System.out.println("DaoImpl.update()");
    }
    
}

最原始的写法,我要在挪用insert()与update()要领前后别离打印时间,就只能界说一个新的类包一层,在挪用insert()要领与update()要领前后别离处理惩罚一下,新的类我定名为ServiceImpl,其实现为:

/**
 * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
 */
public class ServiceImpl {

    private Dao dao = new DaoImpl();
    
    public void insert() {
        System.out.println("insert()要领开始时间:" + System.currentTimeMillis());
        dao.insert();
        System.out.println("insert()要领竣事时间:" + System.currentTimeMillis());
    }
    
    public void delete() {
        dao.delete();
    }
    
    public void update() {
        System.out.println("update()要领开始时间:" + System.currentTimeMillis());
        dao.update();
        System.out.println("update()要领竣事时间:" + System.currentTimeMillis());
    }
    
}

这是最原始的写法,这种写法的缺点也是一目了然:

  • 要领挪用前后输出时间的逻辑无法复用,假如有此外处所要增加这段逻辑就得再写一遍
  • 假如Dao有其它实现类,那么必需新增一个类去包装该实现类,这将导致类数量不绝膨胀
  • 利用装饰器模式

    接着我们利用上设计模式,先用装饰器模式,看看能办理几多问题。装饰器模式的焦点就是实现Dao接口并持有Dao接口的引用,我将新增的类定名为LogDao,其实现为:

    /**
     * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
     */
    public class LogDao implements Dao {
    
        private Dao dao;
        
        public LogDao(Dao dao) {
            this.dao = dao;
        }
    
        @Override
        public void insert() {
            System.out.println("insert()要领开始时间:" + System.currentTimeMillis());
            dao.insert();
            System.out.println("insert()要领竣事时间:" + System.currentTimeMillis());
        }
    
        @Override
        public void delete() {
            dao.delete();
        }
    
        @Override
        public void update() {
            System.out.println("update()要领开始时间:" + System.currentTimeMillis());
            dao.update();
            System.out.println("update()要领竣事时间:" + System.currentTimeMillis());
        }
    
    }

    在利用的时候,可以利用”Dao dao = new LogDao(new DaoImpl())”的方法,这种方法的利益为:

  • 透明,对换用方来说,它只知道Dao,而不知道加上了日志成果
  • 类不会无限膨胀,假如Dao的其它实现类需要输出日志,只需要向LogDao的结构函数中传入差异的Dao实现类即可
  • 不外这种方法同样有明明的缺点,缺点为:

  • 输出日志的逻辑照旧无法复用
  • 输出日志的逻辑与代码有耦合,假如我要对delete()要领前后同样输出时间,需要修改LogDao
  • 可是,这种做法对比最原始的代码写法,已经有了很大的改造。

    利用署理模式

    接着我们利用署理模式实验去实现最原始的成果,利用署理模式,那么我们就要界说一个InvocationHandler,我将它定名为LogInvocationHandler,其实现为:

    /**
     * @author 五月的仓颉http://www.cnblogs.com/xrq730/p/7003082.html
     */
    public class LogInvocationHandler implements InvocationHandler {
    
        private Object obj;
        
        public LogInvocationHandler(Object obj) {
            this.obj = obj;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName = method.getName();
            if ("insert".equals(methodName) || "update".equals(methodName)) {
                System.out.println(methodName + "()要领开始时间:" + System.currentTimeMillis());
                Object result = method.invoke(obj, args);
                System.out.println(methodName + "()要领竣事时间:" + System.currentTimeMillis());
                
                return result;
            }
            
            return method.invoke(obj, args);
        }
        
    }