Spring CGLIB、事务和私有最终字段初始化

Spring CGLIB, transactions and private final field initialization

我的 Spring 引导应用程序中有以下 class 层次结构:

public abstract class A {

    private final ObjectMapper objectMapper = new ObjectMapper();

    public void method1(Object object) {
        this.objectMapper.writeValueAsString(object);
    }

}

@Component
public class B extends A {

    public void method2() {
        method1();
    }

}

在这种情况下一切正常。

但是当我将 @Transactional(rollbackFor = Exception.class) 注释添加到 method2() 声明时,例如:

public abstract class A {

    private final ObjectMapper objectMapper = new ObjectMapper();

    public void method1() {
        this.objectMapper; // always NULL
    }

}

@Component
public class B extends A {

    @Transactional(rollbackFor = Exception.class)
    public void method2() {
        method1();
    }

}

并执行 method2() 它失败了 NullPointerException in method1() 因为 this.objectMapperNULL;

即使添加了@Transactional(rollbackFor = Exception.class),如何让Spring正确初始化private final ObjectMapper objectMapper

此外,在 @Transactional 注释的情况下,this 的 class 是 B$$EnhancerBySpringCGLIB,没有注释只是普通的 B。所以,看起来 CGLIB 无法正确初始化 private final ObjectMapper objectMapper.. 有什么解决方法吗?

删除代码中的 final。您正在使用 @TransactionalCGLIBCGLIB 的工作原理是它通过扩展您的 class 创建一个代理。由于下面的方法是最终的,它不能扩展它,因为最终的 classes 不能被扩展。

@Transactional(rollbackFor = Exception.class)

public final void method2() {
    method1();
}