Java 关键字为'的非序列化注入bean的序列化过程;瞬态';

Java 关键字为'的非序列化注入bean的序列化过程;瞬态';,java,serialization,cdi,Java,Serialization,Cdi,我对java中的序列化有一个问题 下面是一个测试用例类TestLoggerBean: import org.apache.commons.logging.Log; import javax.inject.Inject; import java.io.Serializable; public final class TestLoggerBean implements Serializable{ private static final long serialVersionUID =

我对java中的序列化有一个问题

下面是一个测试用例类
TestLoggerBean

import org.apache.commons.logging.Log;

import javax.inject.Inject;
import java.io.Serializable;


public final class TestLoggerBean implements Serializable{
    private static final long serialVersionUID = 1L;

    @Inject
    protected transient Log logger;

    @Inject
    protected Log logger2;

    public void showMessage() {
        this.logger.info( "Logger 1" );
    }

    public void showMessage2() {
        this.logger2.info( "Logger 2" );
    }
}
测试类:

public class TestClass implements Serializable {
    private static final long   serialVersionUID    = 1L;


    @Inject
    private TestLoggerBean testLoggerBean;

    public void testSerial() {

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutput out = null;

        byte[] yourBytes = null;
        try {
            out = new ObjectOutputStream(bos);
            out.writeObject( this.testLoggerBean );
            out.flush();
            yourBytes = bos.toByteArray();
        } catch (IOException ex) {
            // ignore close exception
        } finally {
            try {
                bos.close();
            } catch (IOException ex) {
                // ignore close exception
            }
        }

        ByteArrayInputStream bis = new ByteArrayInputStream(yourBytes);
        ObjectInput in = null;
        TestLoggerBean o = null;
        try {
            in = new ObjectInputStream(bis);
            o = (TestLoggerBean) in.readObject();
        } catch (IOException ex) {
            // ignore close exception
        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();
        } finally {
            try {
            if (in != null) {
                in.close();
            }
        } catch (IOException ex) {
            // ignore close exception
        }

        o.showMessage2();

        o.showMessage();
    }
}
请参见屏幕截图:

Up:序列化之前的对象

向下:序列化后的对象

我们可以看到瞬态字段为
null
(向上)。 非瞬态字段似乎在序列化后重新注入了对象。对于我的应用程序,非瞬态场的行为很好。请参见示例函数
showmessage 2
。瞬态字段将在方法
showMessage()
中导致
NullPointerException

现在我有以下问题。在我的项目中,对象的序列化非常重要,我对每个有助于检测序列化问题的特性都很满意。My IDE(Intellij)显示非瞬态字段: . 基于我的测试结果,我不能使用关键字“transient”,我的应用程序无法工作。如果没有关键字“transient”,应用程序就可以工作,但我无法使用代码分析功能


我的问题。我的测试用例中是否遗漏了一些常规内容?处理这些情况的最佳方法是什么?测试强制转换中的两个选项对我来说都不是真正可用的。

您可以将记录器设置为静态最终,并避免向记录器注入注释。

与CDI结合使用的
transient
关键字意味着只有在首次实例化此类对象时才会向此类字段注入。例如,首次创建时

如果在此之后的任何时间,对象需要序列化/反序列化
瞬态
字段将不会重新注入(而其他字段将是-这是您使用其他字段观察到的)


如果您销毁这样的bean并重新实例化它(例如,会话bean将过期),那么
transient
字段将再次注入,直到第一次序列化。

感谢您的回答。这证实了我的想法,但对我来说,我仍然不清楚该如何处理这种情况。@SimonA不确定你的情况有什么问题。记录器不可序列化的事实?然后我建议探索它为什么不可序列化。也许IDE给了你一个假阳性,它会工作的。如果没有别的,我想您可以为这些记录器创建一个可序列化的包装器类,然后将其注入。顺便说一句,在你的截图中,非瞬态场被重新注入,即使它是同一类型的记录器;那你为什么需要瞬变呢?我不需要瞬变。但是我需要IDE检查真正有问题的序列化问题。看来这张支票还行。日志不可序列化。我不确定,即使是我对记录器的一般使用,是否还不是一个糟糕的变体,以及我应该如何在可序列化对象中处理非可序列化对象的一般注入。谢谢你的回答,但这些对我来说是不可用的。记录器就是一个例子。我们有类似行为的oder注入。我决定像你描述的那样为记录器制作这个。所以我没有这些日志问题。谢谢你的提示