AOP理解——模拟带有横切逻辑的实例

Spring使用动态代理技术在运行期间织入增强的代码。Spring AOP 使用两种动态代理机制:一种是基于JDK的动态代理;另一种是基于CGLib的动态代理。之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理。

带有横切逻辑的实例

package com.hegx.spring.aop.service.impl;

import com.hegx.spring.aop.Forum;
import com.hegx.spring.aop.PerformanceMonitor;
import com.hegx.spring.aop.dao.ForumDao;
import com.hegx.spring.aop.dao.impl.ForumDaoImpl;
import com.hegx.spring.aop.service.ForumService;

/**
 * @Author: hegx
 * @Description:
 * @Date: 14:25 2017/7/16
 */
public class ForumServiceImpl implements ForumService {

    private ForumDao forumDao = new ForumDaoImpl();

    @Override
    public void remove(Integer forumId) {

        //开始对方法进行性能监视
        PerformanceMonitor.begin("com.hegx.spring.aop.service.impl.ForumServiceImpl.remove");
        forumDao.remove(forumId);
        try {
            Thread.currentThread().sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //结束对方法进行性能监视
        PerformanceMonitor.end();
    }

    @Override
    public void create(Forum forum) {

        //开始对方法进行性能监视
        PerformanceMonitor.begin("com.hegx.spring.aop.service.impl.ForumServiceImpl.remove");

        forumDao.create(forum);

        try {
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //结束对方法进行性能监视
        PerformanceMonitor.end();
    }
}
 
上面带绿色的代码就是具有横切逻辑的代码,每个dao的实现前后都要执行先后的代码,也就是相同的逻辑。

上面的PerformanceMonitor是性能监视的类,我们给出一个非常简单的实现版本,期待吗如下:

package com.hegx.spring.aop;

/**
 * @Author: hegx
 * @Description:
 * @Date: 14:33 2017/7/16
 */
public class PerformanceMonitor {

    //通过一个ThreadLocal保存调用线程先关的性能监视信息
    private static  ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<>();

    //启动对某一个方法的性能监视
    public static void begin(String method)
    {
        System.out.println("begin Monitor...");
        MethodPerformance mp = new MethodPerformance(method);
        performanceRecord.set(mp);
    }

    //启动对某一个方法的性能监视
    public static void end()
    {
        System.out.println("end Monitor...");
        MethodPerformance mp = performanceRecord.get();

        //打印出方法性能监视的结果信息
        mp.printPerformance();
    }

}

ThreadLoacl是将非线程安全类改造成线程安全类的法宝。PerformanceMonitor提供两个方法:通过调用begin(String method)方法开始对目标类方法的监视,method是目标类全限定名;而end()方法结束对目标类方法性能监视,并给出性能监视信息。这两个方法必须配套使用。

用于记录性能类的信息MethodPerformance类的代码如下:

package com.hegx.spring.aop;

/**
 * @Author: hegx
 * @Description:用于记录性能监视信息的类
 * @Date: 14:36 2017/7/16
 */
public class MethodPerformance {

    private Long begin;

    private Long end;

    private String serviceMethod;


    public MethodPerformance(String serviceMethod) {

        this.serviceMethod = serviceMethod;

        this.begin = System.currentTimeMillis();//记录目标类方法的开始执行点的时间
    }

    public void printPerformance()
    {
        end = System.currentTimeMillis();//获取目标类方法执行完成后的系统时间,并进而计算出目标类方法执行时间

        Long elapse = end - begin;

        System.out.println(serviceMethod+"花费了"+elapse+"毫秒");//打印目标类方法执行的时间
        System.out.println();
    }


}

通过下面的代码测试性能监视能力的ForumServiceImpl业务方法:

package com.hegx.spring.aop.test;

import com.hegx.spring.aop.Forum;
import com.hegx.spring.aop.service.ForumService;
import com.hegx.spring.aop.service.impl.ForumServiceImpl;

/**
 * @Author: hegx
 * @Description:测试拥有性能监视能力的TestForumServiceImpl业务方法
 * @Date: 15:10 2017/7/16
 */
public class TestForumService {

    public static void main(String[] args) {
        ForumService forumService = new ForumServiceImpl();

        forumService.remove(10);
        forumService.create(new Forum());
    }


}

程序执行的结果:



如上图和代码所示,当某个方法在进行性能监视,就必须调整方法的代码,在方法体前后分别添加上开启性能和结束性能监视的代码,这些非业务逻辑的性能监视代码破坏了ForumServiceImpl业务逻辑的纯碎性。我们希望通过代理的方式,将业务类方法中开启和结束性能的这些横切代码从业务类中完全移除。并通过JDK动态代理技术或CGLib动态代理技术奖横切代码动态织入到目标方法的位置。










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值