Spring AOP的原理动态代理
Spring AOP简介:
Spring AOP 即面向切面编程,它是面向对象编程oop的一种扩充,可以使用它完成一些通知,日志或者验证等额外需求而不用去修改源代码,这样能够大大提高源代码的整洁性和可读性,因为AOP能让源代码只剩下核心的业务逻辑,在后期的维护也是大有益处。
Spring AOP的五种通知类型:
- 前置通知(Before):方法执行前执行
- 返回通知(AfterRunning):方法返回时执行(若出现异常可以没有方法没有返回则不会执行)
- 异常通知(AfterThrowing):执行方法时发生异常时执行
- 后置通知(After):方法执行后通知(无论是否发生异常)
- 环绕通知(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);
}
}
运行结果: