JavaSpark是否提供对依赖注入或IoC容器的支持?

JavaSpark是否提供对依赖注入或IoC容器的支持?,java,dependency-injection,spark-java,Java,Dependency Injection,Spark Java,在.NET工作过之后,我非常熟悉NancyFX和web API等微web框架对IoC容器的支持 public class HelloWorld { public static void main(String[] args) { get("/hello", (req, res) -> "Hello World"); } } 在类似于Ruby的Sinatra框架中(NancyFX基于Sinatra),您似乎具有依赖注入的能力 据我所见,由于Java spar

在.NET工作过之后,我非常熟悉NancyFX和web API等微web框架对IoC容器的支持

public class HelloWorld {
    public static void main(String[] args) {
        get("/hello", (req, res) -> "Hello World");
    }
}
在类似于Ruby的Sinatra框架中(NancyFX基于Sinatra),您似乎具有依赖注入的能力

据我所见,由于Java spark应用程序作为主要方法运行,因此您似乎无法传递依赖项或IoC容器

public class HelloWorld {
    public static void main(String[] args) {
        get("/hello", (req, res) -> "Hello World");
    }
}
我很难理解这样的框架在没有支持的情况下是如何有用的


如果这个框架不支持,是否还有另一个轻量级框架(我记得Spring不是轻量级的,但可能事情已经改变了)支持这一点?

我最近一直在与Spark合作,它不包括现成的IoC提供商,但是,您可以很容易地包括Spring或Guice core,这将是一个轻量级的解决方案

您所需要做的就是将依赖项添加到Maven并开始使用它


另一种选择是,您可以看看,它是一个完整的堆栈框架,包括Guice、JPA/Hibernate开箱即用。

Spring可以简单地与Spark集成。e、 g

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

}
公共接口火花{
/**
*添加筛选器、路由、异常、WebSocket和其他
*/
无效寄存器();
}
@配置
公共类SparkConfiguration{
@自动连线(必需=错误)
private List sparks=new ArrayList();
@豆子
CommandLineRunner sparkRunner(){
返回args->sparks.stream().forEach(spark->spark.register());
}
}
@组成部分
公共类HelloSpark实现Spark{
@自动连线
私有HelloWorldService HelloWorldService;
@凌驾
公开作废登记册(){
get(“/hello”,(请求,响应)->helloWorldService.hello());
}
}

您可以在

上找到更多信息,通过Java Spark使用Guice非常简单。基本上,为了创建Guice注入器,您需要以以下方式扩展
SparkFilter

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;
    }
}
然后,您需要一个
web.xml
,并且必须使用Jetty或任何其他servlet容器将Spark应用程序作为正常的
war
应用程序运行:

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

火花过滤器
com.devng.spark.guice.SparkGuiceFilter
应用程序类
com.devng.spark.SparkApp
火花过滤器
/*
然而,这种方法有一些局限性。不能对Guice使用基于请求的作用域或会话作用域。如果您不需要它,那么就可以开始了,否则您需要集成Guice Servlet扩展并在
web.xml
中添加
GuiceFilter
,如中所述。您还需要确保在
GuiceFilter
SparkGuiceFilter
中使用相同的注入器实例,为此,您需要在
web.xml
中定义
GuiceServletContextListener


您可以在我的GitHub中找到一个完整的工作示例,我正在使用Spark和Guice进行实验,就我所见,使用这两种工具进行依赖注入非常简单,至少在今天(2017年8月)

您只需执行以下操作:

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

事实上似乎就这么简单。我只是按照指南做的,效果很好。当我运行Spark并打开
http://localhost:4567
在我的浏览器中,将显示从我的方法返回的字符串

使用Guice独立工作
IoC
。它在代码不多的情况下工作;) 链接:

默认情况下不需要GUI模块,检测到自动检测绑定对象

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

通过配置XMLBean而不使用核心之外的库,Spring可以用作轻量级DI。虽然我没有亲自使用过它,但如果你喜欢的话,会有注释。你可以试试Pippo webframework。它支持spring、guice和weld cdi