How to provide your services via @Context in Neo4j unmanaged extension

淺唱寂寞╮ 提交于 2019-12-29 08:12:31

问题


I have Neo4j unmanaged extension. I want some services to be created as singletons and be available via @Context in my resources.

Something like this:

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

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

How this can be achieved?


回答1:


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
    }

    //...
}

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.

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

This will make your PluginLifecycle discoverable by Neo4j server.

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

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

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
    }

    // ...
}

Tip: keep your PluginLifecycle's in same package or in subpackage with your resources.



来源:https://stackoverflow.com/questions/32624603/how-to-provide-your-services-via-context-in-neo4j-unmanaged-extension

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!