在springaop中,cglib代理比动态代理有哪些缺点?

o2g1uqev  于 2021-07-15  发布在  Java
关注(0)|答案(1)|浏览(578)

据我所知,spring aop通常包括:
接口的动态代理
没有的cglib代理(final方法和类除外)
为什么不一直使用cglib代理呢?我预计会有以下收获:
由于它是在编译过程中完成的,因此与动态代理相比,性能应该会有所提高
没有要求接口的限制因素
如果您在某个服务工厂中返回impl类而不进行编译,则可以绕过代理,代价是可配置性。

vcirk6k6

vcirk6k61#

我不确定我是否理解cglib的好处,正如您在问题中介绍的那样。动态代理和cglib都是在运行时创建的,与编译时完全无关。
基本上,cglib的主要缺点是性能。
根据域的不同,性能有两个方面可能或多或少重要:
创建代理对象的成本
代理上方法调用的成本。
现在,在这两种情况下,动态代理机制都比cglib代理更轻量级。这就是为什么springtoversion5(在问号中提到)试图在有接口的情况下创建动态代理,并且只有在不可能的情况下才使用cglib Package 真实对象。
在spring5中,这种情况已经发生了变化,在任何情况下都支持使用cglib,但是仍然有一个标志可以恢复旧的行为。
有趣的是,cglib有一种优势,你没有提到它对spring的重要性(好吧,也许这就是spring5中行为改变的原因,我不能肯定):
许多公司不费心为服务创建接口,直接通过实现工作,或者即使他们这样做了,他们也不使用接口注入:

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是唯一可行的解决方案。

相关问题