如何使用静态常量变量作为 Spring IOC 中列表的输入

发布于 2024-11-27 21:56:20 字数 871 浏览 3 评论 0原文

这就是我需要做的......

我有一个所需的依赖服务的列表。为了举例,我们将它们称为 ServiceA、ServiceB 和 ServiceC。我需要能够在我的 spring 配置文件中定义这些服务的任何排列。例如,我可以

<constructor-arg name="requiredServices">
  <list element-type="string">
    <value>ServiceA</value>
    <value>ServiceB</value>
  </list>
</constructor-arg>

这样表示我需要服务 A 和 B。我的问题是,我在 Spring 文件中使用本地字符串来引用 ServiceA 和 ServiceB,而我更愿意使用系统范围的常量名称服务A和服务B。所以我想我想看到的是

<constructor-arg name="requiredServices">
  <list element-type="string">
    <value>MyStringConstantsFile.ServiceA</value>
    <value>MyStringConstantsFile.ServiceB</value>
  </list>
</constructor-arg>

,如果我们重命名 ServiceA,spring.config 文件仍然可以正常运行。

Here's what I need to do.....

I've got a list of required dependent services. For the sake of example, lets call them ServiceA, ServiceB and ServiceC. I need to be able to define any permutation of those services in my spring configuration file. So for instance I could have

<constructor-arg name="requiredServices">
  <list element-type="string">
    <value>ServiceA</value>
    <value>ServiceB</value>
  </list>
</constructor-arg>

This would indicate that I need services A and B. My problem is, that I'm using local strings in the Spring file to reference ServiceA and ServiceB, when I would much rather use the system wide constant names for ServiceA and ServiceB. So I guess what I'd like to see is

<constructor-arg name="requiredServices">
  <list element-type="string">
    <value>MyStringConstantsFile.ServiceA</value>
    <value>MyStringConstantsFile.ServiceB</value>
  </list>
</constructor-arg>

Then, if we ever rename ServiceA, the spring.config file will still operate properly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╰沐子 2024-12-04 21:56:20

使用 Spring 表达式,您的配置可以如下所示

<object id="myObject" type="q6932134.ServiceClient, q6932134">
  <constructor-arg name="requiredServices">
    <list element-type="string">
      <expression value="MyConstants.ServiceA" />
      <expression value="MyConstants.ServiceB" />
    </list>
  </constructor-arg>
</object> 

:非常接近您的问题中所需的配置:-)

要实现此功能,您必须向 spring 注册您的 MyConstants 类型;将以下代码放在主例程中的某个位置:

TypeRegistry.RegisterType("MyConstants", typeof(MyConstants));

以下替代配置允许您使用对象引用,与您自己的答案非常相似。这使得配置更加冗长,但优点是您的配置文件对重命名代码中的常量变得不那么敏感:

  <object id="svca" type="string">
    <constructor-arg expression="MyConstants.ServiceA" />
  </object>
  <object id="svcb" type="string">
    <constructor-arg expression="MyConstants.ServiceB" />
  </object>

  <object id="myObject" type="q6932134.ServiceClient, q6932134">
    <constructor-arg name="requiredServices">
      <list element-type="string">
        <ref object="svca" />
        <ref object="svcb" />
      </list>
    </constructor-arg>
  </object> 

如果您不喜欢以编程方式注册 MyConstants,您可以将表达式更改为如下:

<constructor-arg expression="T(MyNamespace.MyConstants).ServiceA" />

Using a Spring expression, your configuration can look like this:

<object id="myObject" type="q6932134.ServiceClient, q6932134">
  <constructor-arg name="requiredServices">
    <list element-type="string">
      <expression value="MyConstants.ServiceA" />
      <expression value="MyConstants.ServiceB" />
    </list>
  </constructor-arg>
</object> 

This comes pretty close to desired configuration in your question :-)

For this to work, you do have to register your MyConstants type with spring; put the following code somewhere in your main routine:

TypeRegistry.RegisterType("MyConstants", typeof(MyConstants));

The following alternative configuration allows you to use an object reference, much the same as in your own answer. This makes the configuration more verbose, but has the advantage that your configuration files become less sensitive to renaming your constants in code:

  <object id="svca" type="string">
    <constructor-arg expression="MyConstants.ServiceA" />
  </object>
  <object id="svcb" type="string">
    <constructor-arg expression="MyConstants.ServiceB" />
  </object>

  <object id="myObject" type="q6932134.ServiceClient, q6932134">
    <constructor-arg name="requiredServices">
      <list element-type="string">
        <ref object="svca" />
        <ref object="svcb" />
      </list>
    </constructor-arg>
  </object> 

If you don't like to register your MyConstants programmatically, you can change the expression as follows:

<constructor-arg expression="T(MyNamespace.MyConstants).ServiceA" />
硬不硬你别怂 2024-12-04 21:56:20

这花了一些功夫,但我得到了我需要的东西。您需要分两步解决问题。

首先,为您想要使用的每个常量添加一个条目到您的 spring 配置文件中。我的看起来像这样

<object id="serverAName"
        type="Spring.Objects.Factory.Config.FieldRetrievingFactoryObject, Spring.Core">
  <property name="TargetType" value="CoreNamespace.ConstantsClass, CoreLibrary"/>
  <property name="TargetField" value="ServerAName"/>
</object>

所以在一个名为 CoreLibrary 的程序集中,我有一个名为 ConstantsClass 的类,它存在于命名空间 CoreNamespace 中。

然后,如果我想使用这个常量作为列表的输入,我只需将以下行添加到 spring 配置文件中

<property name="RequiredComponents">
  <list element-type="string">
    <ref object="serverAName"/>
  </list>
</property>

This took a bit of banging, but I got what I needed. You need to solve the problem in two steps.

First, add an entry to your spring config file for every constant you'd like to use. Mine looks like this

<object id="serverAName"
        type="Spring.Objects.Factory.Config.FieldRetrievingFactoryObject, Spring.Core">
  <property name="TargetType" value="CoreNamespace.ConstantsClass, CoreLibrary"/>
  <property name="TargetField" value="ServerAName"/>
</object>

So in an assembly called CoreLibrary, I have a class called ConstantsClass that exists in namespace CoreNamespace.

Then, if I want to use this constant as an input to a list I simply add the following line to the spring config file

<property name="RequiredComponents">
  <list element-type="string">
    <ref object="serverAName"/>
  </list>
</property>
满意归宿 2024-12-04 21:56:20

我不知道 spring 是否支持开箱即用,但您可以在您正在构造的对象的代码中阅读那些带有反射的内容。

或者创建一个像 helper 这样的解析器,而不是分配一个字符串列表,您可以分配一个这些引用的列表,尽管 xml 定义将比现在更详细。

I don't know if spring supports that out of the box, but you could read those with reflection in the code of the object you are constructing.

Or create a parser like helper and instead of assigning a list of strings you could assign a list of those references, although the xml definition will more verbose than it is now.

hth

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文