Spring中AOP概念与两种动态代理模式原理详解
什么是AOP
AOP(Aspect Oriented Programming),面向切面编程,是OOP(Object Oriented Programming)的一个补充,它利用一种称为"切面(Aspect)"的技术,将一些与业务无关,却为业务模块所共同调用的功能,如日志记录、性能统计、安全控制、事务处理等,封装成"切面",并将其对应的代码尽可能地去耦合,从而改进了程序的结构。
AOP 的实现,在Java 中有两种方式,一种是静态代理,一种是动态代理。在Spring框架中,默认使用的是动态代理。
静态代理
代理类的实现
静态代理,是通过编写代理类的方式来实现。代理类与目标类共同实现一个共同的接口或者继承一个共同的抽象类,使得代理类可以对目标类进行功能增强。下面示例代码:
// 被代理对象
public interface Calculator {
int add(int a, int b);
}
// 目标对象
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
}
// 代理对象
public class CalculatorProxy implements Calculator {
private Calculator calculator;
public CalculatorProxy(Calculator calculator) {
this.calculator = calculator;
}
@Override
public int add(int a, int b) {
System.out.println("静态代理:before add");
int result = calculator.add(a, b);
System.out.println("静态代理:after add");
return result;
}
}
静态代理的使用
下面是对静态代理的使用示例代码:
Calculator calculator = new CalculatorImpl();
CalculatorProxy calculatorProxy = new CalculatorProxy(calculator);
int result = calculatorProxy.add(1, 2);
System.out.println("result = " + result);
动态代理
代理类的实现
动态代理是在运行时通过创建一个代理类的对象来间接创建目标对象,动态代理有两种实现方式:一个是Java 自带的动态代理,另一个是CGLib动态代理。
Java 动态代理
Java动态代理是利用反射机制,在运行时动态生成一个代理类,这个代理类就实现了目标对象的接口,从而可以调用目标对象的方法,并在调用前后实现自己的方法增强。
下面是一个实现InvocationHandler接口的代理类的示例代码:
public class CalculatorInvocationHandler implements InvocationHandler {
private Object target;
public CalculatorInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Java动态代理:before " + method.getName());
Object result = method.invoke(target, args);
System.out.println("Java动态代理:after " + method.getName());
return result;
}
}
CGLib 动态代理
CGLib代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。所以,CGLib代理对象要求类不能被final关键字所修饰。
下面是一个实现MethodInterceptor接口的代理类的示例代码:
public class CalculatorMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("CGLib动态代理:before " + method.getName());
Object result = proxy.invokeSuper(obj, args);
System.out.println("CGLib动态代理:after " + method.getName());
return result;
}
}
动态代理的使用
下面是对Java动态代理的使用示例代码:
Calculator calculator = new CalculatorImpl();
CalculatorInvocationHandler calculatorInvocationHandler = new CalculatorInvocationHandler(calculator);
Calculator proxy = (Calculator) Proxy.newProxyInstance(calc.getClass().getClassLoader(), calc.getClass().getInterfaces(), calculatorInvocationHandler);
int result = proxy.add(1, 2);
System.out.println("result = " + result);
下面是对CGLib动态代理的使用示例代码:
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CalculatorImpl.class);
enhancer.setCallback(new CalculatorMethodInterceptor());
CalculatorImpl calculatorProxy = (CalculatorImpl) enhancer.create();
int result = calculatorProxy.add(1, 2);
System.out.println("result = " + result);
总结
本文介绍了Spring中AOP概念与两种动态代理模式原理详解,包括静态代理、Java动态代理和CGLib动态代理。静态代理是通过编写代理类的方式来实现,而动态代理是在运行时通过创建一个代理类的对象来间接创建目标对象,而动态代理有两种实现方式。在Spring框架中,默认使用的是动态代理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring中AOP概念与两种动态代理模式原理详解 - Python技术站