之前为了图方便,对DTO采用匿名内部类的初始化方式之{{}}写法,最终导致了运行时异常,我们还是先看一下详细的console日志吧,server表示服务提供者,client表示服务消费者:
先看看代码是怎么写的:
public class TestDTO implements Serializable {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
@Component
@DubboService
public class TestServiceImpl implements TestService {
@Override
public TestDTO getMessage() {
TestDTO testDTO = new TestDTO() {{
setMessage("hello world.");
}};
return testDTO;
}
}
从代码中可以看到,DTO中有实现序列化接口,但是{{}}匿名初始化的时候,它并没有任何接口实现,因为只要实现了Serializable接口,一定可以序列化。但是他仍然抛出了异常,从异常信息中,我摘出来关键信息:
Java field: final com.dub0.service.TestServiceImpl com.dub0.service.TestServiceImpl$1.this$0
java.lang.RuntimeException: Serialized class com.dub0.service.TestServiceImpl must implement java.io.Serializable
从第一行可以看出,这个java filed不是com.dub0.dto.TestDTO, 而是com.dub0.service.TestServiceImpl com.dub0.service.TestServiceImpl$1.this$0,这就是匿名生成的类TestServiceImpl$1.this$0,它被虚拟机当作了TestServiceImpl的成员,而我们的序列化的基本单位是类,所以从第二行中可以看到序列化的目标是com.dub0.service.TestServiceImpl ,而不是com.dub0.dto.TestDTO,另外还提到了,TestServiceImpl必须实现序列化接口(must implement java.io.Serializable)。因此,只需要实现序列化接口就可以了。
@Component
@DubboService
public class TestServiceImpl implements TestService, Serializable {
@Override
public TestDTO getMessage() {
TestDTO testDTO = new TestDTO() {{
setMessage("hello world.");
}};
return testDTO;
}
}