Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...