如何解决Spring AOP中CGLIB代理相对于动态代理的缺点是什么?
据我了解,Spring AOP一般涉及:
- 接口的动态代理
- 没有的 CGLIB 代理(最终方法和类除外)
为什么不一直使用CGLIB代理?我希望获得以下收益:
- 因为它是在编译期间完成的,所以应该比动态代理有性能提升
- 没有需要接口的限制因素
- 如果你在某个服务工厂返回 impl 类,它可以绕过代理 以无需编译的可配置性为代价。
解决方法
我不确定我是否理解您在问题中提出的 CGLIB 的收益。 动态代理和CGLIB都是在运行时创建的,与编译时完全无关。
基本上,CGLIB 的主要缺点是性能。
性能的两个方面可能或多或少取决于领域:
- 创建代理对象的成本
- 代理上方法调用的成本。
现在,在这两种情况下,动态代理机制都比 CGLIB 代理更轻量级。这就是为什么升级到第 5 版(在问题标签中提到)尝试创建动态代理,如果有一个接口,并且只有当它不可能用 CGLIB 包装真实对象时。
这在 Spring 5 中发生了变化,在任何情况下都支持使用 CGLIB,但仍有一个标志可以恢复旧的行为。
有趣的是,CGLIB 有一种你没有提到的优势,它对 Spring 很重要(好吧,也许这就是 Spring 5 中行为改变的原因,我不能肯定地说):
许多公司不费心为服务创建接口并直接通过实现工作,或者即使他们这样做 - 他们也不使用接口注入:
public interface MyService {
void foo();
}
@Component
public class MyServiceImpl implements MyService {
public void foo() {... whatever...}
}
@Component
public class AnotherService {
@Autowired // note,this is not an injection by inteface
private MyServiceImpl service;
public void bar() {
// do something
service.foo();
// do something else
}
}
现在,如果您将使用动态代理(通常可以在应用程序代码使用接口注入时使用) - 您将生成实现接口 MyService
但不能被注入到 AnotherService
中,因为生成的代理没有扩展 MyServiceImpl
类。在这种情况下,CGLIB 是唯一可行的解决方案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。