我有一个Spring设计问题,这是我以前从未遇到过的:
我有一个管理一堆POJO的应用程序,我想为每个POJO类注册一个工厂,这样集中式@组件就可以进行管理了。就像这样:
class RouteLink implements Link {
}
class HiddenLink implements Link {
}
... lots of others
interface Loader {
Link load(Element xml);
}
@Component
class Manager {
private final Map<String, Loader> loaders = ...
public void create(Element xml) {
// Create link
final String type = ... // from XML
final Loader loader = loaders.get(type);
final Link link = loader.load(xml);
// Do something with the link we created
...
}
}(链接是从XML元素创建的,但这对问题并不重要-它可能来自文本或其他POJO,等等)。
现在,我想共同定位POJO和它相关的Loader。我可以创建一个@Configuration类,为每种类型创建一个@Bean,但这违反了共定位,并要求开发人员(我!)在源文件之间不断切换。
理想情况下,我想做如下事情:
class RouteLink implements Link, Loader {
...
// <--- some Spring magic here to register this as a factory
public Link load(Element xml) {
...
}
}load()方法不能是@Bean或@组件,因为我们正在处理POJO。因此,我被迫创建一个新类,只需调用一个方法:
class RouteLink ... {
...
@Component
public class RouteLinkLoader implements Loader {
public Link load(Element xml) { .... }
}
}装载机是这样向经理注册的:
public Manager(ApplicationContext ctx) {
loaders = ctx.getBeansOfType(Loader.class);
}有点管用,但我忍不住觉得我错过了什么。是否有任何方法将加载方法注册为组件?
备注:
我已经用Spring开发了多年,但是这个设计似乎有一个盲点(或者缺少它!)有没有更好的方法?
发布于 2020-03-26 18:52:11
我不确定我是否正确地理解了您的问题,您想要的是创建将由Spring管理的对象?你看过Spring BeanFactory吗?
发布于 2020-03-27 21:56:25
因此,如果我们想在同一个源文件中共同定位工厂和POJO代码,那么似乎没有神奇的解决方案,基本上必须创建一个单独的@Component来注册POJO工厂。
这意味着我们必须将每个工厂方法包装在一个类中,这样就可以对组件进行扫描,而不是(例如)只有一个静态的类常量来完成它,如下所示:
class PojoClass {
@MagicAnnotationHere
public static final Loader LOADER = xml -> new PojoClass(...);
}无法完成,所以工厂方法变成了一个一流的组件类,这意味着更多的代码:
class PojoClass {
...
@Component
class PojoLoader implements Loader {
@Override
public void load(Element xml) { ... }
}
}从积极的方面来看,工厂可以将@AutoWired放入manager组件中,如下所示:
@Component
class Manager {
@Autowired
private final Map<String, Loader> loaders = new HashMap<>();Spring自动神奇地填充了按bean名称索引的映射,这正是我按名称查找工厂所需要的。我把这叫做平局!
https://stackoverflow.com/questions/60873976
复制相似问题