深圳网站建设黄浦网络 骗子,wordpress本地卡,app网站开发方案,南京百度推广网站1. Spring Boot 中是使用 JDK Proxy 动态代理还是 CGLib ? 首先我们知道在 Spring 里面#xff0c;动态代理的底层#xff0c;默认使用的是 JDK Proxy 代理#xff0c;这一点在官方文档有具体的说明#xff1a; 既然 Spring 中的动态代理默认使用 JDK Proxy#xff0c;那…1. Spring Boot 中是使用 JDK Proxy 动态代理还是 CGLib ? 首先我们知道在 Spring 里面动态代理的底层默认使用的是 JDK Proxy 代理这一点在官方文档有具体的说明 既然 Spring 中的动态代理默认使用 JDK Proxy那么在 Spring Boot 中是否也是使用 JDK Proxy 呢
答案是否Spring Boot 的动态代理默认使用的是 CGLib
这一点在 spring-configuration-metadata.json 文件中有体现 我们带着疑惑来看下面这个案例看看 Spring Boot 中的动态代理是否真的使用了 CGLib
Controller
RestController
RequestMapping(/user)
public class UserController {Autowiredprivate IUserService userService;RequestMapping(/sayhi)public void sayHi() {userService.sayHi();}
}service 接口
public interface IUserService {void sayHi();
}ServiceImpl:
Service
public class UserServiceImpl implements IUserService {Overridepublic void sayHi() {}
}使用 AOP 拦截目标方法
Aspect // 切面
Component
public class LoginAspect {Before(execution(* com.example.demo.service.impl.UserServiceImpl.*(..)))public void doBefore(JoinPoint joinPoint) {System.out.println(拦截 sayHi 方法 joinPoint.getSignature().getName());}
}
打断点启动项目访问 sayhi 接口 此时我们发现 Spring Boot 动态代理底层确实使用了 CGLib 来实现。 【思考一】 我们都知道使用 CGLIb 实现代理被代理类是不能被 final 修饰的因为 CGLib 是通过生成目标类的子类来保证代理类和被代理类的方法名一致从而实现动态代理的那如果上述被代理类使用 final 修饰再次运行程序时它底层是改成 JDK Proxy 代理呢 还是程序执行报错呢
// 被代理类
Service
public final class UserServiceImpl implements IUserService {Overridepublic void sayHi() {}
}运行程序时报错错误信息也很明显 【结论一】 Spring Boot 使用动态代理时底层默认使用的是 CGLib并且是强制性的一旦目标类被 final 修饰了那么程序运行时就会报错而不是使用 JDK Proxy 来完成代理。 如果想要让 Spring Boot 动态代理使用 JDK Proxy 也是可以的不过需要配置两个属性
# 是否启用 AOP
Spring.aop.autotrue
# 代理方式设置为 true 表示强制使用 CGLibfalse 表示使用 JDK
Spring.aop.proxy-target-classfalse
properties 文件中配置了这两属性再次打断点查看确实使用了 JDK
此时就算被代理类使用 final 修饰了也可以被 JDK 代理。 【思考二】 我们都知道 JDK Proxy 实现的动态代理被代理类是需要实现一个接口来保证代理类和被代理类的方法名一致从而实现动态代理的假设使用 JDK Proxy 动态代理时目标类没有实现接口程序运行时是报错呢 还是使用 CGLib 实现代理
// 被代理类
Service
public class UserServiceImpl {public void sayHi() {}
}此时在 Controller 中注入 UserServiceImpl打断点查看这次使用了 CGLib 【最终结论】 1.Spring Boot 默认的动态代理是 CGLib并且是强制性的加上 final项目启动就会报错 2.想让 Spring Boot 使用 JDK 代理需要在配置文件中开启 AOP并把代理方式的属性设为 false才能使用 JDK 代理 3.Spring Boot 使用 JDK 代理时目标类如果没有实现接口程序运行时会使用 CGLib 来实现代理。