java - 将 Spring 依赖注入(inject)到可序列化的 bean 中

标签 java spring serialization dependency-injection

我有一个不可序列化的服务类和一个必须可序列化但必须能够访问该服务类的 bean:

class SomeBean implements Serializable
{
    private StuffFactory factory;

    @Autowired
    public SomeBean(StuffFactory factory)
    {
        this.factory = factory;
    }

    public getOther()
    {
        return this.factory.getSomeOtherStuff();
    }
}

这显然行不通,因为现在 SomeBean 类不再是可序列化的。在 Spring 中解决这个问题的正确方法是什么?当我使 factory 字段成为 transient 时,我是否在反序列化时松开了注入(inject)的工厂实例?当我使 StuffFactory 也可序列化时,此类将不再是单例,因为每个 SomeBean 实例在反序列化后都会有自己的工厂。

最佳答案

要使这个魔法发挥作用,您需要某种背景。

我能想到的一个丑陋的方法是静态 ThreadLocal 持有 ApplicationContext - 这就是 spring-security 使用 SecurityContextHolder 的工作方式。

但如果您能够将需要 StuffFactory 的逻辑外部化为某种单例 SomeBeanService,那就最好了,即:

public class SomeBeanService {
    @Autowired
    private StuffFactory stuffFactory;

    public void doWithSomeBean(SomeBean bean) {
        // do the stuff using stuffFactory here
    }
}

更新:

上述 ThreadLocal 替代方案的重点是完全摆脱 SomeBeanStuffFactory 的依赖。这应该是可能的,但需要更改架构。 关注点分离(不仅是 Spring 的基本规则之一)意味着让 SomeBean 成为一个简单的数据传输对象<可能是个好主意/em> 以及要移动到服务层的业务逻辑。

如果您无法实现这一点,那么唯一的方法就是使用某种static 上下文(正如 Ralph 所说)。此类上下文的实现可能涉及使用 ThreadLocal。这将允许访问 ApplicationContext 以获取 StuffFactory,但它几乎与全局变量一样丑陋,因此请尽可能避免使用它。

更新2:

我刚刚看到您的评论,SomeBean 存储在 HTTP session 中,因此存在序列化/反序列化问题。现在我更建议更改您的设计并删除依赖项。使 SomeBean 成为一个简单的 DTO,尽可能小以避免 session 过载。在 SomeBean 中不应该有需要访问单例 Spring bean 的逻辑。这样的逻辑应该放在controller或者service层。

关于java - 将 Spring 依赖注入(inject)到可序列化的 bean 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7763627/

相关文章:

java - 在android中接收序列化的arraylist

Java 反直觉代码

java - 您如何获得适用于 Android 的简单相机程序?

java - 使用相同用户名创建的 2 个用户在执行 "map.get(user);"时可以有相同的结果吗?

java - Spring Boot 在运行时更改 DataSource 和 JPA 属性

json - 使用 kotlinx.serialization 库反序列化具有不同值类型的 JSON 数组

java - 如何针对较大的 n 值修复快速排序算法? (并且当数组不是随机的时)

java - 不要在 Spring MVC 3 中使用 Jackson 序列化子类型属性

带有 Spring 数据的 Spring 批处理

c# - Protocol Buffer .net : how to handle inheritance without [ProtoInclude]