如何通过Neo4j非托管扩展中的@Context提供服务

时间:2015-09-17 07:20:25

标签: java neo4j

我有Neo4j非托管扩展。我希望将一些服务创建为单身,并在我的资源中通过@Context提供。

这样的事情:

@Path("/example")
public class ExampleResource {

    public ExampleResource(@Context CostlyService costlyService) { // <<---
        // use it here
    }
}

如何实现这一目标?

1 个答案:

答案 0 :(得分:3)

Neo4j具有PluginLifecycle接口,使我们可以进入Neo4j服务器生命周期并提供我们自己的注射服务blog post

所以,我们有服务。我们以此为例:

public interface CostlyService {
}

public class CostlyServiceImpl implements CostlyService {

    public CostlyService() {
        // a LOT of work done here
    }

    //...
}

现在我们需要制作自己的PluginLifecycle实现:

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() {
    }
}

如您所见,可注射列表暂时为空。我们很快就会在那里添加我们的服务。

重要事项:您必须注册PluginLifecycle实施,以便通过SPI提供:

// file: META-INF/services/org.neo4j.server.plugins.PluginLifecycle
my.company.extension.ExamplePluginLifecycle

这将使你的PluginLifecycle被Neo4j服务器发现。

现在我们需要创建实际的注射剂。让我们为Injectable接口编写实现:

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;
    }
}

这将作为我们服务的简单容器。用法:

import static my.company.extension.TypedInjectable.injectable;

injectable(new CostlyServiceImpl(), CostlyService.class);

现在我们可以将我的注射剂添加到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:

提供给我们的资源
@Path("/example")
public class ExampleResource {

    public ExampleResource(@Context CostlyService costlyService) {
        // use it here
    }

    // ...
}

提示:将您的PluginLifecycle保存在与您的资源相同的包或子包中。