【问题标题】:Spring: how to dynamically create multiple beans from single template definitionSpring:如何从单个模板定义动态创建多个 bean
【发布时间】:2012-11-19 12:15:09
【问题描述】:

我有以下 Spring bean 用于在 xml 中定义的远程 Web 服务:

    <bean id="authWSTemplate" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean" abstract="true">
       <property name="serviceInterface" value="com.example.webservices.Authentication" />
       <property name="wsdlDocumentUrl" value="${ws.root}/authentication?wsdl" />
       <property name="namespaceUri" value="http://security.webservices.example.com/" />
       <property name="serviceName" value="AuthenticationWebService" />
       <property name="portName" value="AuthenticationPort" />
       <property name="maintainSession" value="true" />
    </bean>

如何获取这个 bean 模板并创建一个具体的 bean(即提供 root 属性)?然后我可以将具体的 bean 放入 Spring 容器中吗?

我需要大量指向不同系统的具体 bean,所以我有不同的根值。对于此示例,假设有 2 个具有根的系统:http://domain1.com:8001/wshttp://domain2.com:8002/ws

因此,我想要 2 个名为“authWSdom1”和“authWSdom2”的 bean。

我希望在应用程序初始化块中以编程方式执行此操作,在那里我将检索所有已知系统实现的列表(此信息仅在运行时知道),并为每个 impl 创建一个 bean,缓存 bean名称,然后我的应用程序将在需要时从 Spring 容器中检索适当的 bean。

或者,有更好的模式吗?也许通过在 bean 的构造函数中提供根值?

我想我不能在 Spring 中使用单个 bean,因为我需要支持跨多个端点的并发访问(即多个用户同时访问 domain1 和 domain2)。

【问题讨论】:

    标签: java web-services spring


    【解决方案1】:

    创建实现 BeanFactoryPostProcessor 和 InitializingBean 的自定义 bean。 使用 postProcessBeanFactory 方法创建 bean:

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        String wsdlDocumentUrl = ....;
        // .......
        registry.registerBeanDefinition(YOUR_BEAN_NAME, BeanDefinitionBuilder.childBeanDefinition(
                    getParentNoDomainServicBeanName(authWSTemplate)).addPropertyReference(
                    "wsdlDocumentUrl", wsdlDocumentUrl).getBeanDefinition());
    
    }
    

    【讨论】:

      【解决方案2】:

      虽然我相信 Ragnor 的回答是合适的,如果你想在 spring 容器中动态创建 bean,我决定使用 spring 来定义我自己的 WSTemplate DTO,然后使用工厂类来使用这个 DTO 并以编程方式构建(根 url在运行时提供并添加 DTO 后缀值)并缓存生成的 JaxWS ProxyBean:

      <bean id="authWSTemplate" class="com.example.WSProxyTemplate">
         <property name="serviceInterface" value="com.example.webservices.Authentication" />
         <property name="wsdlDocumentUrlSuffix" value="/authentication?wsdl" />
         <property name="namespaceUri" value="http://security.webservices.example.com/" />
         <property name="serviceName" value="AuthenticationWebService" />
         <property name="portName" value="AuthenticationPort" />
         <property name="maintainSession" value="true" />
      </bean>
      

      我喜欢这种方法,因为我的 spring 配置是从实际使用的 WS bean 中抽象出来的。 IE。如果我想使用 JaxWS 以外的其他东西,那么我只需编写一个使用相同 DTO bean 的不同工厂。同样,如果我必须根据某些系统/环境标准在运行时选择 WS 实现,这将有所帮助。

      【讨论】:

        猜你喜欢
        • 2018-11-14
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多