Guice-Guice中的Spring Autowired等效于什么

时间:2018-10-31 18:54:50

标签: java spring dependency-injection inversion-of-control guice

我正在尝试使用Guice,而我来自Spring。

我想知道@Inject是否等效于Spring中的@Autowired,是否可以像在Spring中一样准确地在Web应用程序中使用它。

想象一下,我有一个依赖于服务的Facade,在Spring中我可以为该服务定义一个bean,然后在服务器启动时就可以在Facade中获取该服务的实例。

class FacadeImpl{
  @Autowire Service service;
  ...
}

假设该服务具有具体的实现,Spring会自动将其注入。

Guice有类似的方法吗?我可以做类似的事情

class Facade{
  @Inject Service service;
}

还是只有春天才有的魔力?

在我的Web应用程序中,我正在启动嵌入式tomcat,并且以这种方式使用了google guice模块

Guice.createInjector(new ConfigurationModule());

希望这足以“注入”用@Inject注释的内容。

但是,它不起作用(我并不感到惊讶)。 你们能帮我弄清楚哪个BP注入了对我的Servlet或Facades等的依赖吗??

2 个答案:

答案 0 :(得分:1)

在Guice中,没有@Autowired Spring注释的直接等效项。依赖注入的用法在Getting started page中进行了说明。

1)您必须使用@Inject注释来注释服务的构造函数:

 @Inject
  BillingService(CreditCardProcessor processor, 
      TransactionLog transactionLog) {
    this.processor = processor;
    this.transactionLog = transactionLog;
  }

2)然后在模块中定义类型和实现之间的绑定:

public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {

     /*
      * This tells Guice that whenever it sees a dependency on a TransactionLog,
      * it should satisfy the dependency using a DatabaseTransactionLog.
      */
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);

     /*
      * Similarly, this binding tells Guice that when CreditCardProcessor is used in
      * a dependency, that should be satisfied with a PaypalCreditCardProcessor.
      */
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
  }
}

3)最后构建一个注射器并使用它:

 public static void main(String[] args) {
    /*
     * Guice.createInjector() takes your Modules, and returns a new Injector
     * instance. Most applications will call this method exactly once, in their
     * main() method.
     */
    Injector injector = Guice.createInjector(new BillingModule());

    /*
     * Now that we've got the injector, we can build objects.
     */
    BillingService billingService = injector.getInstance(BillingService.class);
    ...
  }

答案 1 :(得分:1)

是的,在某些条件下,@Inject可以充当@Autowired ...

Guise不需要Module,尽管它们很常用。因此,您可以根据需要摆脱它们。

如果您的课程是具体课程,则可以像@Inject一样直接@Autowired,但您可能还必须标记课程@Singleton,因为Guice的默认范围是不是单例,而是每个人都有新实例,与Spring不同。

Guice不是Spring,但是其中一个的最重要的特征存在于另一个。

在Tomcat中使用Guice

当您想将Guice与Tomcat一起使用时,几乎不需要进行任何配置,但是仍然需要进行配置。您将需要一个Module,但只需要servlet。

在您的 web.xml 中,添加以下内容:

<listener>
  <listener-class>path.to.MyGuiceServletConfig</listener-class>
</listener>

<filter>
  <filter-name>guiceFilter</filter-name>
  <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>guiceFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

MyGuiceServletConfig.java

public class MyGuiceServletConfig extends GuiceServletContextListener {
  @Override protected Injector getInjector() {
    return Guice.createInjector(new ServletModule() {
      @Override protected void configureServlets() {
        serve("/*").with(MyServlet.class); // Nothing else is needed.
      }
    });
  }
}

MyServlet.java

public class MyServlet extends HttpServlet {

  @Inject // Similar to @Autowired
  private MyService myService;

  @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    resp.getWriter().write(myService.hello("Guice"));
  }
}

现在,您可以选择MyService:从中创建接口,然后定义,绑定实现,或者从中创建具体类。

MyService作为界面

MyService.java

@ImplementedBy(MyServiceImpl.class) // This says "hey Guice, the default implementation is MyServiceImpl."
public interface MyService {
  String hello(String name);
}

MyServiceImpl.java

@Singleton // Use the same default scope as Spring
public class MyServiceImpl implements MyService {
  // @Inject dependencies as you wish.
  public String hello(String name) { return "Hello, " + name + "!"; }
}

如果要避免使用@ImplementedBy,仍然可以使用上面的模块,并添加bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);,或在同一Module中编写提供者方法:

@Provides @Singleton MyService provideMyService() {
  return new MyServiceImpl();
}

MyService作为具体课程

MyService.java

@Singleton // Use the same default scope as Spring
public class MyService {
  // @Inject dependencies as you wish.
  public String hello(String name) { return "Hello, " + name + "!"; }
}