以下内容由ChatGPT生成
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,旨在通过分离关注点来提高程序的模块化。Spring AOP 主要用于横切关注点(如日志记录、安全、事务管理等)的实现。在 Spring 中,AOP 的主要功能是为 Bean 增强功能,如添加额外的行为。
静态代理和动态代理是实现 AOP 的两种主要方式。
静态代理:
动态代理:
java.lang.reflect.Proxy
类和 java.lang.reflect.InvocationHandler
接口实现。InvocationHandler
接口中定义了 invoke
方法,当代理对象调用方法时,会执行该方法。import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxyExample {
public static void main(String[] args) {
Foo foo = new FooImpl();
Foo proxyFoo = (Foo) Proxy.newProxyInstance(
Foo.class.getClassLoader(),
new Class<?>[]{Foo.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置增强
System.out.println("Before method: " + method.getName());
Object result = method.invoke(foo, args);
// 后置增强
System.out.println("After method: " + method.getName());
return result;
}
});
proxyFoo.doSomething();
}
}
interface Foo {
void doSomething();
}
class FooImpl implements Foo {
public void doSomething() {
System.out.println("Doing something...");
}
}
super
方法来实现对目标方法的调用。import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxyExample {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Foo.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 前置增强
System.out.println("Before method: " + method.getName());
Object result = proxy.invokeSuper(obj, args);
// 后置增强
System.out.println("After method: " + method.getName());
return result;
}
});
Foo fooProxy = (Foo) enhancer.create();
fooProxy.doSomething();
}
}
class Foo {
public void doSomething() {
System.out.println("Doing something...");
}
}
Spring AOP 支持 JDK 动态代理和 CGLIB 两种代理机制。
Spring 使用 AopProxy
接口和其两个实现类 JdkDynamicAopProxy
和 CglibAopProxy
来分别处理这两种代理机制。
BeanPostProcessor
之一(如 AbstractAutoProxyCreator
的子类)会检查该 Bean 是否需要 AOP 增强。getProxy()
方法来完成的。AopProxy
接口定义了 getProxy()
方法:
JdkDynamicAopProxy
:通过 JDK 动态代理的 Proxy.newProxyInstance()
方法创建代理对象。CglibAopProxy
:通过 CGLIB 的 Enhancer
类创建代理对象。getProxy()
方法返回代理对象。代理对象的创建是在调用 getProxy()
方法时动态生成的,并且在这个方法中处理了所有的 AOP 增强逻辑。
在 JDK 动态代理中,InvocationHandler
的 invoke()
方法包含了拦截器链的逻辑。CglibAopProxy
通过 Callback
和 MethodInterceptor
实现类似的功能。
public class MyInvocationHandler implements InvocationHandler {
private final Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前置处理
System.out.println("Before method: " + method.getName());
// 调用目标对象的方法
Object result = method.invoke(target, args);
// 后置处理
System.out.println("After method: " + method.getName());
return result;
}
}
在 invoke()
方法中:
Spring AOP 中的拦截器链是由 Advisor
和 MethodInterceptor
组成的。Advisor
包含切点(Pointcut)和通知(Advice),切点定义了哪些方法需要拦截,通知则定义了拦截时执行的逻辑。
在代理对象调用方法时:
AopProxy
调用链会依次调用拦截器链中的拦截器。MethodInvocation.proceed()
方法。public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
// 前置处理
System.out.println("Before method: " + invocation.getMethod().getName());
// 调用目标对象的方法
Object result = invocation.proceed();
// 后置处理
System.out.println("After method: " + invocation.getMethod().getName());
return result;
}
}
在 invoke()
方法中,proceed()
方法用于继续执行下一个拦截器或目标方法。如果没有其他拦截器,则执行目标方法。
Spring AOP 使用代理模式实现横切关注点的管理,主要通过 JDK 动态代理和 CGLIB 动态代理实现。代理对象是通过 AopProxy
创建的,其中的 InvocationHandler
和 MethodInterceptor
负责执行拦截器链的逻辑。Spring AOP 提供了强大的功能来增强 Bean 的行为,使得切面逻辑与核心业务逻辑分离,提升了代码的模块化和可维护性。