Spring有许多不同的方法来创建bean,但是是否可以通过反序列化资源来创建bean呢?
我的应用程序有许多组件,每个组件都处理特定类型的数据。在测试期间,数据对象直接实例化,并直接在组件上设置,例如component.setData(someDataObject)。在运行时,数据作为序列化对象可用,并由组件从序列化流读入(流作为资源从Spring上下文传入)。
与让每个组件显式地反序列化来自流的数据相比,让Spring反序列化来自资源的数据对象并将其设置在目标组件上会更一致、更灵活。这样,组件就与它们的数据来源隔离开来。
有没有DeserializerFactoryBean或者类似的东西?
编辑:
以下是一些希望澄清的示例代码:
public class ComponentData implements Externalizable
{
// a complex data structure, behind a simpler interface
}
public class Component
{
private ComponenttData componentData;
public Component(ComponentData data)
{
componentData = data;
}
// other methods that operate using the data
// factory method to create from serialized data
static Component createFromResource(Resource resource)
{
return new Component(deserialize(resource));
}
}有许多类型的组件,并且每种组件类型都与不同的数据实例进行了多次即时转换。
在测试中,组件及其ComponentData实例是在代码中构造的。在生产中,使用具有"factory- method“属性的spring-bean来调用静态Componnet.createFromResource方法,该方法对来自资源的数据进行反序列化。有许多类型的组件,并且每种组件都有相同的静态方法来从反序列化的数据构造。由于重复,这本身看起来很糟糕。在我看来,测试和生产中的组件构造并不相同,这似乎也很奇怪。如果可以将反序列化移到Spring上下文中,则可以删除组件上的静态方法,然后所有依赖注入都由Spring完成,而不必将其作为特殊情况进行编码。
我想像这样的事情
<bean name="componentData" class="DeserializingFactoryBean">
<constructor-arg value="/data/componentData1.dat"/> <!-- resource -->
</bean>
<bean name="component" class="Component">
<constructor-arg ref="componentData"/>
</bean>当我最初发表文章时,我认为这可能是存在的,但我担心我可能错过了大量的spring javadoc。从最初的响应来看,Spring似乎没有反序列化的工厂bean。
如果DeserializingFactoryBean不是正确的方法,还有什么替代方法?
发布于 2010-05-01 02:33:58
这是给其他发帖者的评论。正如他们所指出的,Spring中没有反序列化工厂支持,所以我创建了一个。
下面是通过反序列化从资源创建beans的FactoryBean的代码。默认情况下,会创建一个实例,并为每次使用返回相同的实例。您可以将属性singleton设置为false,每次使用时都会反序列化一个新的实例。
它的用法如下
<bean name="myBean" class="DeserializingFactoryBean">
<property name="source" value="mybean.ser"/>
<property name="objectType" value="org.acme.MyBean"/>
</bean>和代码
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import java.io.BufferedInputStream;
import java.io.ObjectInputStream;
public class DeserializingFactoryBean extends AbstractFactoryBean
{
private Resource source;
private Class<?> objectType;
private int deserializationCount;
public DeserializingFactoryBean()
{
}
public DeserializingFactoryBean(Resource source, Class<?> objectType)
{
this.source = source;
this.objectType = objectType;
}
public void afterPropertiesSet() throws Exception
{
Assert.notNull(objectType, "Property 'objectType' may not be null");
Assert.notNull(source, "Property 'source' may not be null");
super.afterPropertiesSet();
}
public Resource getSource()
{
return source;
}
public void setSource(Resource source)
{
this.source = source;
}
public void setObjectType(Class<?> objectType)
{
this.objectType = objectType;
}
public Class getObjectType()
{
return objectType;
}
@Override
protected Object createInstance() throws Exception
{
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(source.getInputStream()));
Object result = oin.readObject();
if (!objectType.isInstance(result))
throw new ClassCastException(String.format("Deserialized object is not an instance of %s",objectType.getName()));
oin.close();
return result;
}
}发布于 2010-04-27 20:12:09
有
DeserializerBeanFactory或类似的东西吗?
我从来没有听说过,坦率地说,我不希望我的初始化被不透明的(仅仅是人类的)序列化对象控制。
但是,如果您真的认为这是一个好主意(嗯),那么创建一个以这种方式工作的自定义BeanFactory应该不难。
发布于 2010-04-27 20:30:04
是的,您可以实现自己的your工厂,就像为SimpleJndiBeanFactory所做的那样。但我不确定,这就是你想要的。您需要在应用程序上下文中使用额外的bean。我将实现一个从流中加载bean的BeanFactoryPostProcessor,并对它们执行autowire或register操作。
https://stackoverflow.com/questions/2720929
复制相似问题