我目前正在尝试使用 Guice 在 Java 控制台应用程序中实现注入(inject)。该应用程序导入数据库中的 XML 文件。每个导入操作都在 AbstractImporter
中完成,它可以是 UserImporter
、ScheduleImporter
等。
public class ScheduleMigrator extends AbstractMigrator {
private final UserImporter userImporter;
private final ScheduleImporterFactory scheduleImporterFactory;
@Inject
public ScheduleMigrator(UserImporter userImporter,
ScheduleImporterFactory scheduleImporterFactory) {
this.userImporter = userImporter;
this.scheduleImporterFactory = scheduleImporterFactory;
}
public void migrate() {
// Migrate users
userImporter.run();
// Migrate schedules for each type
for (ScheduleType scheduleTypes : ScheduleType.values()) {
ScheduleImporter importer =
scheduleImporterFactory.create(scheduleTypes);
importer.run();
}
}
}
public class UserImporter extends AbstractImporter {
private final UserTransformer userTransformer;
private final ConfigurationService configurationService;
@Inject
public UserImporter(UserTransformer userTransformer,
ConfigurationService configurationService) {
this.userTransformer = userTransformer;
this.configurationService = configurationService;
}
public void run() {
// do stuff here
}
}
@Singleton
public class UserTransformer {
// ...code ommited...
}
@ImporterScoped
public class ConfigurationService {
// ...code ommited...
}
我已成功为仅在 Importer
中可用和实例化的类创建了自己的作用域 (@ImporterScoped
)。该范围是按照 the wiki 中的步骤创建的。 。我的问题是,我应该如何进入和退出 ScheduleMigrator
中的范围?
正如您在 ScheduleMigrator
中看到的,每个 Importer
都会被注入(inject),并调用其 run()
方法。还有工厂(基于 Guice 的 @AssistedInject
功能)。这是我希望每个作用域开始和结束的地方,UserImporter
和 ScheduleImporterFactory
应该在它们自己的作用域中运行。
这是我想要实现的目标的粗略想法:
importerScope.enter();
(new UserImporter()).run();
importerScope.exit();
Guice 的文档提到了拦截器的使用,但我对如何实现它有点迷失。
最佳答案
使用 AOP 似乎是一种过度设计的方法,可能会带来问题。我什么时候进入范围?我什么时候退出?如果我实例化两个 Importer
对象会发生什么?
相反,我在 AbstractMigrator
中添加了一个 runScoped
方法,该方法接受 Runnable
并执行它。使用注入(inject),我获得了 ImporterScope 范围,并适本地进入和退出它。
protected void runScoped(Runnable function)
{
scenarioScope.enter();
try {
function.run();
}
finally {
scenarioScope.exit();
}
}
用法:
runScoped(() -> {
ScheduleImporter importer =
scheduleImporterFactory.create(scheduleTypes);
importer.run();
});
但这会带来一个问题。在 ScheduleMigrator
中,我无法注入(inject) Importers
,因为它们的实例化将发生在范围之外,并且 Guice 会抛出 OutOfScopeException
。我必须将每个 Importer
包装在 Provider
中。
private final Provider<UserImporter> userImporterProvider;
runScoped(() -> {
UserImporter importer = userImporterProvider.get();
importer.run();
});
关于java - Java 控制台应用程序中的 Guice 自定义范围进入和退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37775601/