Spring AOP的原理之动态代理

Spring AOP的原理动态代理

Spring AOP简介:

Spring AOP 即面向切面编程,它是面向对象编程oop的一种扩充,可以使用它完成一些通知,日志或者验证等额外需求而不用去修改源代码,这样能够大大提高源代码的整洁性和可读性,因为AOP能让源代码只剩下核心的业务逻辑,在后期的维护也是大有益处。

Spring AOP的五种通知类型:

  1. 前置通知(Before):方法执行前执行
  2. 返回通知(AfterRunning):方法返回时执行(若出现异常可以没有方法没有返回则不会执行)
  3. 异常通知(AfterThrowing):执行方法时发生异常时执行
  4. 后置通知(After):方法执行后通知(无论是否发生异常)
  5. 环绕通知(Around):围绕着方法执行,以下整个动态代理就可以看成环绕通知

Spring AOP的原理实现(动态代理):

接口类Calculator

package com.ldx.proxy;

public interface Calculator {

    public int add(int i,int j);
    public int sub(int i,int j);
    public int mul(int i,int j);
    public int div(int i,int j);

}

接口实现类CalculatorImpl:

package com.ldx.proxy;

public class CalculatorImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        return i+j;
    }

    @Override
    public int sub(int i, int j) {
        return i-j;
    }

    @Override
    public int mul(int i, int j) {
        return i*j;
    }

    @Override
    public int div(int i, int j) {
        return i/j;
    }
}

代理类LoggingProxy:

package com.ldx.proxy;

import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

import java.lang.reflect.Method;
import java.util.Arrays;

public class LoggingProxy {

    private Calculator target;

    public LoggingProxy(Calculator target) {
        this.target = target;
    }

    public void setTarget(Calculator target) {
        this.target = target;
    }

    public Calculator getCalculator(){
        Calculator calculator=null;

        ClassLoader cl=target.getClass().getClassLoader();
        Class[] interfaces=new Class[]{Calculator.class};
        InvocationHandler h=new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("前置通知:方法"+method.getName()+"执行前,参数为"+ Arrays.asList(objects));
                Object result=null;
                try{
                  result=method.invoke(target,objects);
                  System.out.println("返回通知:方法"+method.getName()+"返回值:"+result);
               }catch (Exception e){
                    System.out.println("异常通知:"+e);
                    throw new Exception(e);
                }
                System.out.println("后置通知:方法"+method.getName()+"后置通知");

                return result;
            }
        };
        calculator=(Calculator)Proxy.newProxyInstance(cl,interfaces,h);
        return calculator;
    }
}

测试类Test:

package com.ldx.proxy;

public class Test {
    public static void main(String[] args) {
        Calculator calculator=new CalculatorImpl();
        calculator=new LoggingProxy(calculator).getCalculator();
        System.out.println("-------加法-------");
        calculator.add(1,2);
        System.out.println("-------减法-------");
        calculator.sub(3,1);
        System.out.println("-------乘法-------");
        calculator.mul(4,3);
        System.out.println("-------无异常除法-------");
        calculator.div(4,2);
        System.out.println("-------异常除法-------");
        calculator.div(4,0);
    }
}

运行结果:
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值