2015-08-19 19 views
6

Essendo stato in .NET, sono esperto nel supporto che i framework Web micro come NancyFX e Web API hanno per i contenitori IoC.Java Spark fornisce supporto per l'iniezione di dipendenza o contenitori IoC?

In framework simili a Ruby come Sinatra (NancyFX è basato su Sinatra) sembra che tu abbia la possibilità di eseguire l'iniezione di dipendenza.

Da quello che vedo, poiché le applicazioni spark di Java vengono eseguite come metodo principale, non sembra che si possa passare nelle proprie dipendenze o contenitori IoC.

public class HelloWorld { 
    public static void main(String[] args) { 
     get("/hello", (req, res) -> "Hello World"); 
    } 
} 

Ho difficoltà a capire come un framework come questo potrebbe essere utile senza supportarlo.

Se questo framework non funziona, c'è un altro framework leggero (Spring non è leggero da quello che ricordo, ma forse le cose sono cambiate) che supporta questo?

+0

Spring * può * essere utilizzato come DI leggero configurando i bean XML e non utilizzando librerie al di fuori del core. Anche se non l'ho usato personalmente, c'è l'annotazione [@Inject] (http://www.vogella.com/tutorials/DependencyInjection/article.html) se questo sembra qualcosa nel tuo vicolo. –

+1

Puoi provare i Webframework di Pippo. Ha supporto per primavera, guice e saldatura cdi –

risposta

0

Ultimamente ho lavorato con Spark e non include un fornitore IoC, ma è possibile includere facilmente Spring o Guice core e questa sarebbe una soluzione leggera.

Tutto ciò che devi fare è aggiungere la dipendenza a Maven e iniziare a usarlo.

In alternativa, si guarderebbe Ninja, che è un framework a stack completo e include Guice, JPA/Hibernate out of the box.

8

La molla può essere semplicemente integrata con Spark. per esempio.

public interface Spark { 

    /** 
    * adds filters, routes, exceptions, websockets and others 
    */ 
    void register(); 

} 

@Configuration 
public class SparkConfiguration { 

    @Autowired(required = false) 
    private List<Spark> sparks = new ArrayList<>(); 

    @Bean 
    CommandLineRunner sparkRunner() { 
     return args -> sparks.stream().forEach(spark -> spark.register()); 
    } 

} 

@Component 
public class HelloSpark implements Spark { 

    @Autowired 
    private HelloWorldService helloWorldService; 

    @Override 
    public void register() { 
     get("/hello", (request, response) -> helloWorldService.hello()); 
    } 

} 

Potete trovare più https://github.com/pmackowski/spring-boot-spark-java

2

E 'abbastanza facile da usare Guice con Java Spark. Fondamentalmente è necessario estendere lo SparkFilter nel modo seguente per creare l'iniettore Guice.

public class SparkGuiceFilter extends SparkFilter { 

    private Injector injector = null; 

    @Override 
    protected SparkApplication[] getApplications(final FilterConfig filterConfig) throws ServletException { 
     final SparkApplication[] applications = super.getApplications(filterConfig); 

     if (this.injector == null) { 
      this.injector = Guice.createInjector(new MainModule()); 
     } 

     if (applications != null && applications.length != 0) { 
      for (SparkApplication application : applications) { 
       this.injector.injectMembers(application); 
      } 
     } 

     return applications; 
    } 
} 

Allora avete bisogno di un web.xml e devono eseguire l'applicazione Spark come una normale applicazione utilizzando war Jetty o qualsiasi altro contenitore di servlet:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
     version="3.0"> 

    <filter> 
     <filter-name>SparkGuiceFilter</filter-name> 
     <filter-class>com.devng.spark.guice.SparkGuiceFilter</filter-class> 
     <init-param> 
      <param-name>applicationClass</param-name> 
      <param-value>com.devng.spark.SparkApp</param-value> 
     </init-param> 
    </filter> 
    <filter-mapping> 
     <filter-name>SparkGuiceFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 
</web-app> 

Tuttavia, ci sono alcune limitazioni con questo approccio. Non è possibile utilizzare ambiti basati su richiesta o sessione con Guice. Se non hai bisogno di questo, allora sei a posto, altrimenti devi integrare Guice Servlet Extensions e aggiungere GuiceFilter nel tuo web.xml come descritto in the official Guice documentation. È inoltre necessario assicurarsi di utilizzare la stessa istanza dell'iniettore nello GuiceFilter e nello SparkGuiceFilter per fare ciò che è necessario definire uno GuiceServletContextListener nello web.xml come descritto in here.

Si può trovare un esempio completamente funzionante nel mio GitHub qui https://github.com/devng/demo/tree/master/sparkjava-guice

1

realtà sto sperimentando con Spark e Guice e, per quanto posso vedere, utilizzando l'iniezione di dipendenza utilizzando sia è molto semplice, almeno a partire dal oggi (agosto 2017).

Tutto quello che dovete fare è la seguente:

public class MySparkApplication { 

    public static void main(String[] args) { 

     Injector injector = Guice.createInjector(); 
     SomeClass someClass = injector.getInstance(SomeClass.class); 

     get("/hello", (req, res) -> someClass.getSomeString()); 
    } 
} 

Sembra davvero di essere facile come quello. Ho appena seguito la guida Guice Getting Started e funziona. Quando eseguo Spark e apro http://localhost:4567 nel mio browser, viene visualizzata la stringa che viene restituita dal mio metodo.

0

Lavorare da solo IoC with Guice. Funziona trovare con non un sacco di codice;) Link:https://github.com/Romain-P/SparkJava-JFast

Nessun modulo Guice necessaria per impostazione predefinita, Auto-detect vengono rilevati oggetti vincolanti.

public class Main { 
    public static void main(String[] args) { 
     /* give a class as argument for package scanning from its path recursively */ 
     Injector injector = SparkApplication.init(Application.class); 
     injector.getInstance(Application.class).initialize(); 
    } 
} 

@Binding 
public class Application { 
    @Inject Service http; 
    @Inject HelloController helloController; 

    public void initialize() { 
     http.port(8080); 
     http.get("/hello", (req, res) -> helloController.hello()); 
    } 
} 

@Binding 
public class HelloController { 
    @Inject HelloService service; 

    public Object hello() { 
     //business logic 
     return service.hello(); 
    } 
} 

@Binding 
@Slf4j 
public class HelloService { 
    public Object hello() { 
     log.info("hello"); 
     return new Object(); 
    } 
}