在运行时更改弹簧豆实现
我有一个接口和多个实现。我正在自动将界面接线以供使用。我需要在运行时选择不同的实现。
public class Util {
public void getClient();
}
。
public class UtilOne implements Util {
public void getClient() {...}
}
public class UtilTwo implements Util {
public void getClient() {...}
}
@Configuration
public class AppConfig {
@Autowired
@Bean
@Primary
public Util utilOne() {
return new UtilOne();
}
@Autowired
@Bean
public Util utilTwo() {
return new UtilTwo();
}
}
@Component
public class DemoService {
@Autowired
private Util util;
}
由于某种原因,如果我们无法将客户端进入UTILONE,则我想在不重新启动应用程序的情况下切换到Utiltwo 我想将DemoService中的util对象更改为Utiltwo对象。 属性active.util
将来自数据库,我们可以从UI更新。
I have an Interface and multiple implementation. I'm auto wiring the interface in classes for usage. I need to choose different implementation at runtime.
public class Util {
public void getClient();
}
Implementations
public class UtilOne implements Util {
public void getClient() {...}
}
public class UtilTwo implements Util {
public void getClient() {...}
}
@Configuration
public class AppConfig {
@Autowired
@Bean
@Primary
public Util utilOne() {
return new UtilOne();
}
@Autowired
@Bean
public Util utilTwo() {
return new UtilTwo();
}
}
@Component
public class DemoService {
@Autowired
private Util util;
}
For some reason if we are unable to get client in UtilOne, I want to switch to UtilTwo without restarting the app. I want to change the Util object in DemoService to UtilTwo object.
Property active.util
will come from DB and can we updated from UI.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
它不起作用 - 如果您有一定的实现UTIRE的实现,例如,class sampleclass(这是单身人士),则不能真正将UTIT的实现更改为不同的事物,而无需重新启动应用程序上下文。
因此,我没有这样做,而是建议替代方案。您说,在某些条件下,在运行时评估您要切换实现。它是什么样的条件?是否可以提取此条件决策逻辑?
如果是这样,您可以自动使用特殊的DynamiCutil,该动态可以保留所有utils的参考,并根据条件将所需的UTIL调用:
现在,使用这样的设计,您可以动态地添加新的可能的结果(以及应该实现它们的utils。您在系统中的课程将必须自动
dynamicutil
,因此有效地您会引入一个额外的间接级别,但会获得灵活性It doesn't work this way - if you have a certain implementation of Util wired to, say, class SampleClass (which is a singleton) you can't really change the implementation of the Util to something different without restarting the application context.
So instead of going this way, I suggest an alternative. You say that under certain conditions that evaluate in runtime you want to switch implementations. What kind of condition it is? Is it possible to extract this condition decision logic?
If so, you can autowire a special DynamicUtil that will hold the reference to all the utils and will call the required util depending on the condition:
Now with such a design you can dynamically add new possible outcomes (along with utils that should implement them. You classes in the system will have to autowire
DynamicUtil
though, so effectively you'll introduce one additional level of indirection but will gain flexibility您可以尝试使用委派代理进行接近。拥有一个主
util
bean,它只是围绕实际实现包装,并允许在运行时更改其内部代表。此外,您可以创建类似的经理/助手类,该类别持有对所有实际实现bean的参考,以简化它们之间的切换。在适用切换逻辑的地方:
请注意,这只是示意图的示例,您应该注意诸如豆类创建订单,预选器注入(也许是条件),初始化等细节。
You can try approach with delegating proxy. Have a primary
Util
bean that is just wrapper around actual implementation and allow to change its internal delegate at runtime. In addition you can create something like manager/helper class that holds references to all actual implementation beans to simplify switching between them.And where switching logic applies:
Note, this is only schematic example, you should take care about details like bean creation order, injection with qualifiers (maybe conditional), initialization and so on.
这是根据您的情况进行的简单方法。主要想法是读取
active.util
propertyservice
tb的属性,并将您的utils包装到route> outeutil
:in demoService中:
您可以更改<<<<<<< :代码> Active.util 要在不重新启动应用程序的情况下选择哪个UTIT在运行时使用。
Here is a simple approach based on your situation. The main idea is that read
active.util
property from DB byPropertyService
and wrap your Utils intoRouteUtil
:and in DemoService:
You can change
active.util
to select which Util will be used at runtime without restarting the app.春季为您提供了我个人不喜欢的解决方案。您可以做的是声明一个
myinterface
是您的接口,列表将包含所有实现。但是,我(由于我不喜欢这种解决方案)编写了自己的解决方案,在那里您可以拥有一个由所有实现的静态工厂。因此,您不必注入所有实现,而是按班级名称或自定义的名称从工厂中选择它们。另一个优势是,自定义的名称必须是每个工厂唯一的。因此,可以说您有一些分阶段的过程,在每个阶段,您都有自己的界面和自己的工厂。因此,您可以具有相同的自定义名称,以实现不同的接口。假设您使用文本格式XML,JSON和CSV,并为SAVE-1阶段2阶段3具有一个接口(和相关工厂)。因此,对于每个阶段-X iNteface,您可以使用命令命名JSON
,XML
和csv
,因此您要做的就是具有一个称为<<的变量Code> CurrentType 将保存值之一 -JSON
,XML
和csv
,对于每个阶段,您都可以使用工厂要获得适当的实现:其中
阶段[x]处理程序
是您的接口。但这只是一个额外的兴趣。我的解决方案可在开源Mgntutils库中获得。有关此特定锻炼的文章可以在此处找到:春季框架中对“孤儿”豆的非侵入式访问另外,我在图书馆中描述了此功能Javadoc 在这里。可以找到该库为 maven trifact “ https://github.com/michaelgantman/mgnt/releases” rel =“ nofollow noreferrer”> github 包括源代码和javadocSpring provides you a solution which I personally didn't like. What you can do is declare a
Where
MyInterface
is your interface and list will contain all the implementations. However, I (since I didn't like this solution) wrote my own solution, where you can have a static factory that is self-populated by all implementations. So you don't have to inject all your implementations but choose them at run-time from a factory either by class name or by custom-defined name. An additional advantage is that the custom-defined name must be unique per factory. So lets say you have some staged process and for each stage you have your own interface and your own factory. So you can have the same custom defined names for your implementations of different interfaces. Say you working with text formats XML, JSON and CSV and have an interface (and related factory) for say stage-1 stage-2 stage-3. So for each stage-X inteface you can have implemetations namedJSON
,XML
andCSV
so all you have to do is have a variable calledcurrentType
that will hold one of the values -JSON
,XML
andCSV
and for each stage you can use the factory to get the appropriate implementation:where
Stage[X]Handler
is your interface. But this is just an additional benifit. My solution is available in Open-source MgntUtils library. The article about this particular fiture could be found here: Non-intrusive access to "Orphaned" Beans in Spring framework Also, I describe this feature in my library javadoc here. The library could be found as Maven artifact and on Github including source code and Javadoc