我有一个不可序列化的服务类和一个必须可序列化但必须有权访问此服务类的bean:
class SomeBean implements Serializable
{
private StuffFactory factory;
@Autowired
public SomeBean(StuffFactory factory)
{
this.factory = factory;
}
public getOther()
{
return this.factory.getSomeOtherStuff();
}
}
这显然不起作用,因为现在SomeBean类不再可序列化.在Spring中解决这个问题的正确方法是什么?当我将工厂现场设置为瞬态时,我是否在反序列化时松开了注入的工厂实例?当我使StuffFactory也可序列化时,这个类将不再是一个单例,因为每个SomeBean实例在反序列化之后将拥有它自己的工厂.
我能想到的一个丑陋的方法是持有ApplicationContext的静态ThreadLocal – 它是Spring-security如何使用SecurityContextHolder工作的.
但是,如果你能够将需要StuffFactory的逻辑外化到某种单独的SomeBeanService,即:
public class SomeBeanService {
@Autowired
private StuffFactory stuffFactory;
public void doWithSomeBean(SomeBean bean) {
// do the stuff using stuffFactory here
}
}
更新:
上面替代ThreadLocal的重点是完全摆脱SomeBean对StuffFactory的依赖.这应该是可能的,但需要改变架构.关注点的分离(不仅是Spring,基本规则之一)意味着让SomeBean成为一个简单的数据传输对象并将业务逻辑移动到服务层可能是个好主意.
如果你无法实现这一点,那么唯一的方法是使用某种静态上下文(正如拉尔夫所说).这种上下文的实现可能涉及使用ThreadLocal.这将允许访问ApplicationContext以获取StuffFactory,但它几乎和全局变量一样难看,所以尽可能避免使用它.
UPDATE2:
我刚看到你的评论,SomeBean存储在HTTP会话中,因此序列化/反序列化问题.现在我建议更改你的设计并删除依赖.使SomeBean成为一个简单的DTO,尽可能小以避免重载会话.应该没有逻辑要求访问SomeBean中的单例Spring bean.这种逻辑应放在控制器或服务层中.