Spring学习基础(四):SpringAOP(1) JDK动态代理模式实现简单的日志框架

概述:
AOP即Aspect Oriented Programming
意为面向切面编程
AOP的主要功能有日志记录、性能统计、安全控制、事务处理和异常处理
核心概念:
Spring AOP就像一把刀,在代码的执行的过程中,可以随意的插入和拔出。在插入和拔出的位置可以“任意妄为”的做自己喜欢的事。

名称说明
横切关注点对哪些方法进行拦截,拦截后如何处理
切面(Aspect)类是对物体特征的抽象,切面就是对横向关注点的抽象
连接点(Joinpoint)被拦截到的点(方法,字段,构造器)
切入点(Pointcut)对连接点进行拦截的定义
通知(Advice)拦截到连接点之后要执行的代码,通知分为前置,后置,异常,最终,环绕
目标对象代理的目标对象
织入(Weave)将切面应用到目标对象并导致代理对象创建的过程
引入(Introduction)在不修改代码的情况下,引用可以在运行期间为类动态的添加一些方法或字段

Advice通知类型:

名称说明
前置通知(Before Advice)在连接点前面执行,一般不影响连接点的执行,除非此处抛出异常
正返回通知(After Returning Advice)在连接点正常执行完成后执行,如果连接点异常,则不会执行
异常返回通知(After Throwing Advice)在连接点抛出异常后执行
后通知(After (finally) Advice)在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容
环绕通知(Around Advice)围绕在连接点前后,环绕通知是最强大的通知类型。环绕通知还需要负责决定是继续处理连接点还是中断执行

SpringAOP内部是使用动态代理模式实现的,下面我们通过JDK动态代理模式实现一个最简单的日志框架:

1.首先在HellowHermit项目包com.hermit.test下创建业务接口类BusinessClassService

package com.hermit.test;

public interface BusinessClassService {
    void doSomething();
}

2.在com.hermit.test下创建业务的实现类BusinessClassServiceImpl

package com.hermit.test;

public class BusinessClassServiceImpl implements BusinessClassService{
    public void doSomething(){
        System.out.println("HuaWei number one!");
    }
}

3.然后编写日志类接口MyLogger

package com.hermit.test;

import java.lang.reflect.Method;

public interface MyLogger {
    /**
     * 记录进入方法的时间
     */
    void saveIntoMethodTime(Method method);
    /**
     * 记录推出方法的时间
     */
    void saveOutMethodTime(Method method);
}

4.编写MyLoggerImpl实现类

package com.hermit.test;

import java.lang.reflect.Method;

public class MyLoggerImpl implements MyLogger{
    @Override
    public void saveIntoMethodTime(Method method) {
        System.out.println("进入"+method.getName()+"方法的时间为"+System.currentTimeMillis());
    }

    @Override
    public void saveOutMethodTime(Method method) {
        System.out.println("退出"+method.getName()+"方法的时间为"+System.currentTimeMillis());
    }
}

5.最后,编写最重要的类:MyLoggerHandler

package com.hermit.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyLoggerHandler implements InvocationHandler {
    //原始对象
    private Object objOriginal;
    //关键
    private MyLogger myLogger = new MyLoggerImpl();

    public MyLoggerHandler(Object object){
        super();
        this.objOriginal = object;
    }
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
        Object result = null;
        //日志类的方法:保存进入方法的时间
        myLogger.saveIntoMethodTime(method);
        //调用代理方法
        result = method.invoke(this.objOriginal,args);
        //日志类的方法:保存退出方法的时间
        myLogger.saveOutMethodTime(method);
        return result;
    }
}

6.我们来编写一个测试的类MyLoggerTest

package com.hermit.test;

import java.lang.reflect.Proxy;

public class MyLoggerTest {
    public static void main(String args[]){
        //实例化业务类
        BusinessClassService businessClassService = new BusinessClassServiceImpl();
        //日志类的handler
        MyLoggerHandler myLoggerHandler = new MyLoggerHandler(businessClassService);
        //获得代理类对象
        BusinessClassService businessClass = (BusinessClassService)
                Proxy.newProxyInstance(businessClassService.getClass().
                        getClassLoader(),businessClassService.getClass().getInterfaces(),
                        myLoggerHandler);
        //执行代理类方法
        businessClass.doSomething();
    }
}

运行成功如下:
运行截图
以上是利用JDK动态代理模式实现的简单的日志框架
总结步骤:
1.创建一个实现InvocationHandler接口的类MyLoggerHandler,实现invoke()方法。
2.创建被代理的类BusinessClassService以及接口BussinessClassServiceImpl
3.调用Proxy的静态方法newProxyInstance,创建一个代理类
4.通过代理类调用方法

实现
实现
实现
saveIntoMethodTime
Invoke
saveOutMethodTime
实现
MyLogger
MyLoggerImpl
InvocationHandler
MyLoggerHandler
MyLogger
MyLoggerImpl
doSomething
BusinessClassServiceImpl
BusinessClssService
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜狼狼与灰太杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值