Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过反序列化创建Springbean_Java_Spring_Serialization_Javabeans - Fatal编程技术网

Java 通过反序列化创建Springbean

Java 通过反序列化创建Springbean,java,spring,serialization,javabeans,Java,Spring,Serialization,Javabeans,Spring有许多不同的创建bean的方法,但是可以通过反序列化资源来创建bean吗 我的应用程序有许多组件,每个组件都处理特定类型的数据。在测试过程中,数据对象直接实例化并直接在组件上设置,例如component.setData(someDataObject)。在运行时,数据作为序列化对象可用,并由组件从序列化流中读入(该流作为资源从Spring上下文中传入) 与其让每个组件从流中显式地反序列化其数据,不如让Spring从资源中反序列化数据对象并在目标组件上设置它,这样会更加一致和灵活。这样,

Spring有许多不同的创建bean的方法,但是可以通过反序列化资源来创建bean吗

我的应用程序有许多组件,每个组件都处理特定类型的数据。在测试过程中,数据对象直接实例化并直接在组件上设置,例如component.setData(someDataObject)。在运行时,数据作为序列化对象可用,并由组件从序列化流中读入(该流作为资源从Spring上下文中传入)

与其让每个组件从流中显式地反序列化其数据,不如让Spring从资源中反序列化数据对象并在目标组件上设置它,这样会更加一致和灵活。这样,组件就与它们的数据来源隔离开来

是否有反序列化FactoryBean或类似的东西

编辑:

下面是一些希望澄清的示例代码:

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));
   }
}
组件有多种类型,每种组件类型都会使用不同的数据实例多次实例化

在测试中,组件及其组件数据仪器是在代码中构造的。在生产中,使用具有“factory method”属性的Springbean来调用静态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>

当我最初发布时,我认为这可能存在,但我认为我可能错过了巨大的SpringJavadocs。从最初的响应来看,Spring似乎没有反序列化工厂bean

如果反序列化的GfactoryBean不是正确的方法,那么有哪些替代方法

是否有
反序列化BeanFactory
或类似的东西

从来没有听说过,坦白说,我不希望我的初始化被不透明(对人类而言)的序列化对象控制


但是,如果您真的认为这是一个好主意(嗯哼),那么创建一个自定义的
BeanFactory
就不难了。

是的,您可以像done for一样实现自己的BeanFactory。但我不确定,那是你想要的。在应用程序上下文中需要额外的bean。我将实现一个从流中加载bean和/或它们的方法。

这是对其他海报的评论。正如他们所指出的,Spring中没有反序列化工厂支持,所以我创建了一个

下面是通过从资源反序列化创建bean的代码。默认情况下,将创建一个实例,并为每次使用返回相同的实例。您可以将属性
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;
    }
}
import org.springframework.beans.factory.config.AbstractFactoryBean;
导入org.springframework.core.io.Resource;
导入org.springframework.util.Assert;
导入java.io.BufferedInputStream;
导入java.io.ObjectInputStream;
公共类DeserializengFactoryBean扩展了AbstractFactoryBean
{
私人资源来源;
私有类objectType;
私有int反序列化计数;
public反序列化gfactorybean()
{
}
public DeserializengFactoryBean(资源源,类objectType)
{
this.source=源;
this.objectType=objectType;
}
public void afterPropertieSet()引发异常
{
Assert.notNull(objectType,“属性'objectType'不能为null”);
Assert.notNull(source,“属性‘source’不能为null”);
super.afterPropertiesSet();
}
公共资源getSource()
{
返回源;
}
public void setSource(资源源)
{
this.source=源;
}
public void setObjectType(类objectType)
{
this.objectType=objectType;
}
公共类getObjectType()
{
返回objectType;
}
@凌驾
受保护对象createInstance()引发异常
{
ObjectInputStream oin=新的ObjectInputStream(新的BufferedInputStream(source.getInputStream());
对象结果=oin.readObject();
如果(!objectType.isInstance(结果))
抛出新的ClassCastException(String.format(“反序列化对象不是%s的实例”,objectType.getName());
oin.close();
返回结果;
}
}

序列化类是一个复杂的语言数据块,由复杂而漫长的过程生成。我意识到序列化可能很脆弱,但是,在这种情况下,代码和数据将始终保持一致。数据可以表示为XML或其他(对人类)透明的格式,但我看不出这样做有什么好处——原始数据不是为人眼准备的!尺寸将大大增加。序列化具有有效的用途,因此将其作为bean的源绑定到spring中似乎是有意义的。@mdma-您的用例是一个非常不寻常的用例。不管怎样,一家定制的豆工厂应该能帮你完成这项工作。谢谢你的意见,阿恩。使用BeanFactoryPostProcessor可以在特定情况下很好地工作(例如,根据bean名称从资源中配置每个bean-BeanFactoryPostProcessor配置了从bean名称到资源的映射,类似于Spring MVC中的映射),它确实涉及相当多的连接和约定(例如,使用哪个setter来