【发布时间】:2018-10-27 17:45:28
【问题描述】:
我有一个命令行 Java SE 应用程序,我想对其进行一些现代化改造。我想在其他 CDI 功能中使用拦截器和依赖注入。然而,该应用程序在设计时并未考虑 CDI 或依赖注入,它广泛使用 new 关键字和构造函数参数,而不是将对象创建委托给 DI 容器。 CDI/Weld 不会在使用 new 创建的对象上注入依赖项或运行拦截器,它根本无法处理构造函数参数。一个简化的例子:
class Main {
@Inject
private SomeModule someModule;
public static void main (String[] args) {
SeContainer container = ... set up CDI container ...
Main main = container.select(Main.class).get();
main.main(args);
}
@TraceLog
public Main () {
...
}
@TraceLog
public main (String[] args) {
Encryptor = new Encryptor(args[1], args[2], args[3]);
encryptor.run();
}
}
class Encryptor {
@Inject
private SomeModule someModule;
private String inputFile;
private String outputFile;
private String key;
@TraceLog
public Encryptor (String inputFile, String outputFile, String key) {
...
}
@TraceLog
public run () {
...
}
}
Main 被 CDI 容器实例化, someModule 被注入,@TraceLog 拦截器被构造函数和方法调用。但是 Encryptor 是使用 new 关键字显式创建的,没有注入 someModule,也没有调用 @TraceLog。
CDI 支持以编程方式创建 bean,但仅适用于具有无参数非私有构造函数的类。例子:
CDI.current().select(DefinitelyNotEncryptor.class).get();
@Inject
private Instance<DefinitelyNotEncryptor> instance;
instance.select(DefinitelyNotEncryptor.class).get();
Spring supports injection into objects created with the new keyword, with the use of AspectJ。虽然不知道对构造函数和方法上的拦截器的支持。
@Configurable(preConstruction = true)
@Component
class Encryptor {
@Autowired
private SomeModule someModule;
private String inputFile;
private String outputFile;
private String key;
@TraceLog
public Encryptor (String inputFile, String outputFile, String key) {
...
}
@TraceLog
public run () {
...
}
}
是否有与 CDI/Weld 类似的解决方案?还是我应该求助于使用 Spring?是否支持构造函数和方法拦截器?
【问题讨论】:
标签: java spring dependency-injection cdi weld