【问题标题】:Implement interface in runtime Java EE and Spring在运行时 Java EE 和 Spring 中实现接口
【发布时间】:2016-05-31 19:53:24
【问题描述】:

我想在运行时基于变量实现接口。

例子:

Class A implements interface1 {
    public getValue() {}
}

Class B implements interface1 {
    public getValue() {}
}

所以我想在配置中设置变量...,例如ClasstoImplement=A

所以,如果ClasstoImplement=A,那么我需要调用类A.getValue()

如果ClasstoImplement=B,那么我需要在运行时调用Class B.getValue()。而且我应该能够在运行时更改ClasstoImplement 的值。

我的应用程序基于 Spring 并在 Tomcat 中运行。

谁能帮我看看有没有办法?

【问题讨论】:

  • 您可以将这两种实现都注入到您的类中,并根据读取外部存储的配置参数调用正确的实现。

标签: spring


【解决方案1】:

有许多可能的解决方案。其中之一是使用org.springframework.aop.target.HotSwappableTargetSource。 看看可以考虑的实现:

public class CustomSwappable<T> implements Interface1 {

    private HotSwappableTargetSource targetSource;

    private String key;

    private Map<String, T> swappableBeans;

    @PostConstruct
    private void init() {
        targetSource = new HotSwappableTargetSource(swappableBeans.values().iterator().next()); // first is the default
    }

    // you need to track changes in config and call this method if any modifications were done
    public void configChanged(String key, String value) {
        if (!this.key.equals(key)) {
            return;
        }
        if (!swappableBeans.containsKey(value)) {
            return;
        }
        targetSource.swap(swappableBeans.get(value));
    }

    @Override
    public String getValue() {
        return ((Interface1)targetSource.getTarget()).execute();
    }

    @Required
    public void setConfigurationKey(String key) {
        this.key = key;
    }

    @Required
    public void setSwappableBeans(Map<String, T> swappableBeans) {
        this.swappableBeans = swappableBeans;
    }

}

和bean声明应该如下:

<bean id="Interface1Swappable" class="path.to.CustomSwappable">
        <property name="configurationKey" value="swappableKey"/>
        <property name="swappableBeans">
            <util:map value-type="path.toInterface1">
                <!-- first is default -->
                <entry key="classA">
                    <bean class="path.to.class.A"/>
                </entry>
                <entry key="classB">
                    <bean class="path.to.class.B"/>
                </entry>
            </util:map>
        </property>
    </bean>

【讨论】:

  • 感谢您的信息。我有 2 个错误。一个是“SampleService”给出错误。我们还需要在界面中定义“configChanged”吗?
  • @Dev 关于第一个问题,您应该将其替换为“Interface1”而不是 SampleService。 'configChanged' 不应该被覆盖,我的错误。将此代码视为演示示例。实际的实现应该根据你的需要来完成。
  • 谢谢。在运行时,我将如何将实现从 ClassA 更改为 ClassB。请告诉我...
猜你喜欢
  • 2017-10-15
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 2011-07-13
  • 2020-09-07
  • 1970-01-01
相关资源
最近更新 更多