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.objectMapper
是 NULL
;
即使添加了@Transactional(rollbackFor = Exception.class)
,如何让Spring正确初始化private final ObjectMapper objectMapper
?
此外,在 @Transactional
注释的情况下,this
的 class 是 B$$EnhancerBySpringCGLIB
,没有注释只是普通的 B
。所以,看起来 CGLIB 无法正确初始化 private final ObjectMapper objectMapper
.. 有什么解决方法吗?
删除代码中的 final
。您正在使用 @Transactional
和 CGLIB
。 CGLIB
的工作原理是它通过扩展您的 class 创建一个代理。由于下面的方法是最终的,它不能扩展它,因为最终的 classes 不能被扩展。
@Transactional(rollbackFor = Exception.class)
public final void method2() {
method1();
}
我的 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.objectMapper
是 NULL
;
即使添加了@Transactional(rollbackFor = Exception.class)
,如何让Spring正确初始化private final ObjectMapper objectMapper
?
此外,在 @Transactional
注释的情况下,this
的 class 是 B$$EnhancerBySpringCGLIB
,没有注释只是普通的 B
。所以,看起来 CGLIB 无法正确初始化 private final ObjectMapper objectMapper
.. 有什么解决方法吗?
删除代码中的 final
。您正在使用 @Transactional
和 CGLIB
。 CGLIB
的工作原理是它通过扩展您的 class 创建一个代理。由于下面的方法是最终的,它不能扩展它,因为最终的 classes 不能被扩展。
@Transactional(rollbackFor = Exception.class)
public final void method2() {
method1();
}