我知道CGLIB用于Spring Boot中的代理,并且CGLIB不会覆盖任何私有方法。但是,如果您尝试使用自注入来调用私有方法,则可以毫无异常地调用它。
我很好奇为什么它可以毫无例外地被调用。另外,我想知道为什么其他自动装配对象将为空,因为我尝试测试自注入如何在纯 JAVA 中工作,它不会为空。
public class AClass {
private String value;
public AClass(String value) {
this.value = value;
}
public static void main(String[] args) {
AClass a = new ProxyClass("test");
a.print();
}
private void print() {
System.out.println(this.value);
}
}
public class ProxyClass extends AClass {
public ProxyClass(String value) {
super(value);
}
}
输出将为“test”,而不是 null
如果您在 Spring Boot 中这样做,如下所示:
@Service
@RequiredArgsConstructor
public class TestService {
private final TestService testService;
private final Object otherBean;
public void publicTest(){ // callee = TestService
otherBean.doSomeThing();
}
private void privateTest(){ // callee = TestService$$SpringCGLIB and all autowired are null
otherBean.doSomeThing();
}
}
当你在publicTest()处断点时,你会发现“this”是TestService。
当你在 privateTest() 处断点时,你会发现“this”是 TestService$$SpringCGLIB 但所有自动装配的都是 null。但是,如果CGLIB不重写私有方法,为什么它可以毫无异常地调用privateTest()。
CGLIB 代理不会覆盖私有方法,并且自注入通过反射而不是代理继承来工作。 通过调用 Direct 私有方法,您可以强制它绕过 Spring 的代理机制。 因此您可能希望通过代理(自注入实例)访问 Spring 管理的 bean 来调用方法。
@Service
@RequiredArgsConstructor
public class TestService {
private final TestService testService;
private final Object otherBean;
public void publicTest() {
// This will work correctly with all autowired beans
testService.protectedTest();
}
// Change from private to protected
protected void protectedTest() {
otherBean.doSomeThing();
}
}