问题描述
我有Neo4j非托管扩展.我希望将某些服务创建为单例,并可以通过资源中的@Context
来使用.
I have Neo4j unmanaged extension. I want some services to be created as singletons and be available via @Context
in my resources.
类似这样的东西:
@Path("/example")
public class ExampleResource {
public ExampleResource(@Context CostlyService costlyService) { // <<---
// use it here
}
}
这如何实现?
推荐答案
Neo4j具有 PluginLifecycle 接口,使我们有可能进入Neo4j服务器生命周期,并提供我们自己的注入服务博客文章.
Neo4j has PluginLifecycle interface that give us possibility to hook into Neo4j server lifecycle and provide our own services for injection blog post.
因此,我们有服务.让我们以这个为例:
So, we have service. Let's take this one as example:
public interface CostlyService {
}
public class CostlyServiceImpl implements CostlyService {
public CostlyService() {
// a LOT of work done here
}
//...
}
现在,我们需要创建自己的PluginLifecycle
实现:
Now we need to make our own PluginLifecycle
implementation:
public class ExamplePluginLifecycle implements PluginLifecycle {
@Override
public Collection<Injectable<?>> start(GraphDatabaseService graphDatabaseService,
Configuration config) {
final List<Injectable<?>> injectables = new ArrayList<>();
return injectables;
}
@Override
public void stop() {
}
}
如您所见,可注射列表目前为空.我们将很快在那添加我们的服务.
As you see, injectable list is empty for now. We will add our service there soon.
重要提示::您必须注册您的PluginLifecycle
实现,这样它才能通过SPI使用:
Important: you must register your PluginLifecycle
implementation, so it will be available via SPI:
// file: META-INF/services/org.neo4j.server.plugins.PluginLifecycle
my.company.extension.ExamplePluginLifecycle
这将使Neo4j服务器可以发现您的PluginLifecycle
.
This will make your PluginLifecycle
discoverable by Neo4j server.
现在我们需要创建实际的注射剂.让我们为Injectable
接口编写实现:
Now we need to create actual injectable. Let's write implementation for Injectable
interface:
public final class TypedInjectable<T> implements Injectable<T> {
private final T value;
private final Class<T> type;
private TypedInjectable(final T value, final Class<T> type) {
this.value = value;
this.type = type;
}
public static <T> TypedInjectable<T> injectable(final T value, final Class<T> type) {
return new TypedInjectable<>(value, type);
}
@Override
public T getValue() {
return value;
}
@Override
public Class<T> getType() {
return type;
}
}
这将作为我们服务的简单容器.用法:
This will serve as simple container for our service. Usage:
import static my.company.extension.TypedInjectable.injectable;
injectable(new CostlyServiceImpl(), CostlyService.class);
现在我们可以将注射剂添加到PluginLifecycle
.
Now we can add our injectable into PluginLifecycle
.
@Override
public Collection<Injectable<?>> start(GraphDatabaseService graphDatabaseService,
Configuration config) {
final List<Injectable<?>> injectables = new ArrayList<>();
injectables.add(injectable(new CostlyServiceImpl, CostlyService.class)); // <<---
return injectables;
}
此更改后,我们的CostlyService可通过@Context用于我们的资源:
After this change our CostlyService will be available for our resources via @Context:
@Path("/example")
public class ExampleResource {
public ExampleResource(@Context CostlyService costlyService) {
// use it here
}
// ...
}
提示:将PluginLifecycle与资源放在同一软件包或子软件包中.
Tip: keep your PluginLifecycle's in same package or in subpackage with your resources.
这篇关于如何通过Neo4j非托管扩展中的@Context提供服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!