【Spring Boot实战与进阶】AOP的两种动态代理(JDK和Cglib)
在Spring AOP中,有两种动态代理的方式:JDK动态代理和Cglib动态代理。
- JDK动态代理:用于代理实现了接口的类。它是通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口实现的。
- Cglib动态代理:用于代理没有实现接口的类。它是通过继承的方式生成代理类,因此不能代理被final修饰的类。
下面是使用Spring AOP的JDK动态代理和Cglib动态代理的例子:
- 使用JDK动态代理:
@Aspect
@Component
public class LogAspect {
@Around("execution(* com.example.service.impl.*.*(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Method: " + joinPoint.getSignature().getName() + " start with arguments: " + Arrays.toString(joinPoint.getArgs().toString()));
Object result = joinPoint.proceed();
System.out.println("Method: " + joinPoint.getSignature().getName() + " end with result: " + result);
return result;
}
}
- 使用Cglib动态代理:
@Aspect
@Component
public class LogAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Method: " + joinPoint.getSignature().getName() + " start with arguments: " + Arrays.toString(joinPoint.getArgs().toString()));
Object result = joinPoint.proceed();
System.out.println("Method: " + joinPoint.getSignature().getName() + " end with result: " + result);
return result;
}
}
在这两个例子中,我们定义了一个切面LogAspect
,它将在对应的service包下所有方法执行前后进行日志记录。
注意:
- 对于使用JDK动态代理的类,它们必须至少实现一个接口。
- 对于使用Cglib动态代理的类,它们不能被final修饰符修饰。
- 通过
@Aspect
注解,我们声明这是一个切面类。 - 通过
@Around
注解,我们声明了一个建言(advice),它将在方法执行前后执行。 - 通过
ProceedingJoinPoint
,我们可以获取当前被建议的方法和参数,并且可以通过proceed()
方法来执行当前方法。
评论已关闭