【问题标题】:Does Java Spark provide any support for dependency injection or IoC containers?Java Spark 是否为依赖注入或 IoC 容器提供任何支持?
【发布时间】:2022-05-07 23:13:09
【问题描述】:

在 .NET 中,我精通 NancyFX 和 Web API 等微型 Web 框架对 IoC 容器的支持。

在 Ruby 中的类似框架中,例如 Sinatra(NancyFX 基于 Sinatra),您似乎具有依赖注入的能力。

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

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

如果不支持,我很难理解这样的框架如何有用。

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

【问题讨论】:

  • Spring 可以通过配置 XML bean 而不使用核心之外的库来用作轻量级 DI。虽然我没有亲自使用过它,但如果它看起来像你的小巷子,那么有 @Inject 注释。
  • 你可以试试 Pippo 网络框架。它支持 spring、guice 和焊接 cdi

标签: java dependency-injection spark-java


【解决方案1】:

Spring 可以简单地与 Spark 集成。例如

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

}

您可以在https://github.com/pmackowski/spring-boot-spark-java上找到更多信息

【讨论】:

    【解决方案2】:

    将 Guice 与 Java Spark 一起使用非常容易。基本上,您需要通过以下方式扩展SparkFilter 才能创建 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;
        }
    }
    

    那么您需要一个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>
    

    但是,这种方法存在一些限制。您不能在 Guice 中使用基于请求的范围或会话范围。如果您不需要这个,那么您可以继续使用,否则您需要集成 Guice Servlet Extensions 并在您的web.xml 中添加GuiceFilter,如the official Guice documentation 中所述。您还需要确保在GuiceFilterSparkGuiceFilter 中使用相同的注入器实例,您需要在web.xml 中定义GuiceServletContextListener,如here 所述。

    你可以在我的 GitHub https://github.com/devng/demo/tree/master/sparkjava-guice找到一个完整的工作示例

    【讨论】:

      【解决方案3】:

      我实际上正在尝试使用 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());
          }
      }
      

      实际上似乎就这么简单。我只是按照Guice Getting Started 指南进行操作,它可以工作。当我运行 Spark 并在浏览器中打开 http://localhost:4567 时,会显示从我的方法返回的字符串。

      【讨论】:

        【解决方案4】:

        我最近一直在使用 Spark,它不包括开箱即用的 IoC 提供程序,但是,您可以轻松地包括 Spring 或 Guice core,这将是一个轻量级的解决方案.

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

        作为替代方案,您可以查看Ninja,它是一个全栈框架,包括开箱即用的 Guice、JPA/Hibernate。

        【讨论】:

          【解决方案5】:

          独自工作IoC with Guice。它可以在没有很多代码的情况下找到;) 链接: https://github.com/Romain-P/SparkJava-JFast

          默认不需要guice模块,自动检测绑定对象。

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

          【讨论】:

            【解决方案6】:

            我认为the neutrino framework 符合您的要求。

            免责声明:我是 neutrino 框架的作者。

            什么是中微子框架

            它是一个基于Guice的apache spark依赖注入框架,旨在减轻开发的序列化工作。

            与 spark 上仅在驱动程序上应用 DI 的旧 DI 解决方案不同,neutrino 提供了使用 DI 在执行器处生成对象甚至在那里控制它们的范围的能力。

            详情请参考the neutrino readme file

            限制

            由于这个框架使用 scala 宏来生成一些类,guice 模块和如何连接这些模块的逻辑需要用 scala 编写。其他类可以是java。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-11-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-01-04
              • 1970-01-01
              • 2018-09-13
              相关资源
              最近更新 更多