使用 FactoryModuleBuilder 的 HK2 等效辅助注入
HK2 equivalent Assisted Injection with FactoryModuleBuilder
感谢迁移到 jersey 2,我需要从 guice 迁移到 HK2。对于我的一些依赖项,我有一个辅助注入方法,我无法在 HK2 中实现它。看起来它应该通过 Custom Injection Resolvers 解决,但我真的不知道如何解决。这些例子对我来说不够清楚..
这是它在 Guice 上的样子:
public interface MyFactory {
public MyClass createMyClass(@Assisted String dynamicParameter);
public HisClass createHisClass(@Assisted String dynamicParameter);
...
}
binder.install(new FactoryModuleBuilder().build(MyFactory.class));
public class MyClass {
...
@Inject
public MyClass(@Assisted String dynamicParameter, SomeService someOtherServiceInjectedAutomatically){
...
}
}
如何在 HK2 上实现这个?
发布问题后我想到了这样做:
public class MyFactoryImpl implements MyFactory{
private final SomeService someService;
@Inject
public MyFactoryImpl(SomeService someService){
this.someService = someService;
}
public MyClass createMyClass(String dynamicParameter){
return new MyClass(dynamicParameter, someService);
}
...
}
有个Guice-Bridge:-D
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>guice-bridge</artifactId>
<version>${hk2.version}</version>
</dependency>
这是一个使用 Guice 3.0 和 HK2 2.3.0(与 Jersey 2.13 捆绑在一起)的示例。这只是一个独立的,但它应该在 Jersey 环境中工作。
Guice classes
public class GuiceGreeter {
public String getGreeting(String name) {
return "Hello, " + name;
}
}
import com.google.inject.assistedinject.Assisted;
import javax.inject.Inject;
public class Message {
private final String message;
@Inject
public Message(GuiceGreeter greeter, @Assisted String name) {
message = greeter.getGreeting(name);
}
public String getMessage() {
return message;
}
}
public interface GuiceMessageFactory {
public Message getMessage(String name);
}
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
public class GuiceMessageModule extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder().build(GuiceMessageFactory.class));
bind(GuiceGreeter.class);
}
}
注入 Guice 工厂的 HK2 服务
import javax.inject.Inject;
public class HK2Service {
private final GuiceMessageFactory messageFactory;
@Inject
public HK2Service(GuiceMessageFactory messageFactory) {
this.messageFactory = messageFactory;
}
public void printMessage(String name) {
System.out.println(messageFactory.getMessage(name).getMessage());
}
}
主要
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.ServiceLocatorFactory;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
import org.jvnet.hk2.guice.bridge.api.GuiceBridge;
import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge;
public class Main {
public static void main(String[] args) {
// Create service locator. In Jersey context, you should be able to
// inject the `ServiceLocator` into the `Application/ResourceConfig`
// subclass constructor, or as a field
ServiceLocatorFactory factory = ServiceLocatorFactory.getInstance();
ServiceLocator locator = factory.create("SimpleServiceLocator");
// bridge the two frameworks to allow Guice injected services
GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
Injector injector = Guice.createInjector(new GuiceMessageModule());
GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);
// Add my HK2 Service
ServiceLocatorUtilities.addClasses(locator, HK2Service.class);
// Look up HK2 service. If this lookup works, `@Inject` in Jersey should.
HK2Service service = locator.getService(HK2Service.class);
service.printMessage("peeskillet");
}
}
这会打印出 "Hello, peeskillet"
。请参阅下面的评论 main
方法以在 Jersey 应用程序中获取 ServiceLocator
。如果您不熟悉 ServiceLocator
,您使用 AbstractBinder
添加的所有绑定也将放入服务定位器上下文中,因此您不必显式添加 class 正如我在上面所说的那样 HK2Service
。
感谢迁移到 jersey 2,我需要从 guice 迁移到 HK2。对于我的一些依赖项,我有一个辅助注入方法,我无法在 HK2 中实现它。看起来它应该通过 Custom Injection Resolvers 解决,但我真的不知道如何解决。这些例子对我来说不够清楚..
这是它在 Guice 上的样子:
public interface MyFactory {
public MyClass createMyClass(@Assisted String dynamicParameter);
public HisClass createHisClass(@Assisted String dynamicParameter);
...
}
binder.install(new FactoryModuleBuilder().build(MyFactory.class));
public class MyClass {
...
@Inject
public MyClass(@Assisted String dynamicParameter, SomeService someOtherServiceInjectedAutomatically){
...
}
}
如何在 HK2 上实现这个?
发布问题后我想到了这样做:
public class MyFactoryImpl implements MyFactory{
private final SomeService someService;
@Inject
public MyFactoryImpl(SomeService someService){
this.someService = someService;
}
public MyClass createMyClass(String dynamicParameter){
return new MyClass(dynamicParameter, someService);
}
...
}
有个Guice-Bridge:-D
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>guice-bridge</artifactId>
<version>${hk2.version}</version>
</dependency>
这是一个使用 Guice 3.0 和 HK2 2.3.0(与 Jersey 2.13 捆绑在一起)的示例。这只是一个独立的,但它应该在 Jersey 环境中工作。
Guice classes
public class GuiceGreeter {
public String getGreeting(String name) {
return "Hello, " + name;
}
}
import com.google.inject.assistedinject.Assisted;
import javax.inject.Inject;
public class Message {
private final String message;
@Inject
public Message(GuiceGreeter greeter, @Assisted String name) {
message = greeter.getGreeting(name);
}
public String getMessage() {
return message;
}
}
public interface GuiceMessageFactory {
public Message getMessage(String name);
}
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
public class GuiceMessageModule extends AbstractModule {
@Override
protected void configure() {
install(new FactoryModuleBuilder().build(GuiceMessageFactory.class));
bind(GuiceGreeter.class);
}
}
注入 Guice 工厂的 HK2 服务
import javax.inject.Inject;
public class HK2Service {
private final GuiceMessageFactory messageFactory;
@Inject
public HK2Service(GuiceMessageFactory messageFactory) {
this.messageFactory = messageFactory;
}
public void printMessage(String name) {
System.out.println(messageFactory.getMessage(name).getMessage());
}
}
主要
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.api.ServiceLocatorFactory;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
import org.jvnet.hk2.guice.bridge.api.GuiceBridge;
import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge;
public class Main {
public static void main(String[] args) {
// Create service locator. In Jersey context, you should be able to
// inject the `ServiceLocator` into the `Application/ResourceConfig`
// subclass constructor, or as a field
ServiceLocatorFactory factory = ServiceLocatorFactory.getInstance();
ServiceLocator locator = factory.create("SimpleServiceLocator");
// bridge the two frameworks to allow Guice injected services
GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
Injector injector = Guice.createInjector(new GuiceMessageModule());
GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(injector);
// Add my HK2 Service
ServiceLocatorUtilities.addClasses(locator, HK2Service.class);
// Look up HK2 service. If this lookup works, `@Inject` in Jersey should.
HK2Service service = locator.getService(HK2Service.class);
service.printMessage("peeskillet");
}
}
这会打印出 "Hello, peeskillet"
。请参阅下面的评论 main
方法以在 Jersey 应用程序中获取 ServiceLocator
。如果您不熟悉 ServiceLocator
,您使用 AbstractBinder
添加的所有绑定也将放入服务定位器上下文中,因此您不必显式添加 class 正如我在上面所说的那样 HK2Service
。