简体   繁体   English

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

[英]Guice - what is the equivalent of Spring Autowired in Guice

I am trying to use Guice and I am coming from Spring. 我正在尝试使用Guice,而我来自Spring。

I am wondering if @Inject is the equivalent of @Autowired in Spring and if I can use it in web application exactly as I am using it in Spring. 我想知道@Inject是否等效于Spring中的@Autowired ,以及是否可以像在Spring中一样使用它在Web应用程序中使用。

Imagine I have a Facade which depends on a service, in Spring I can define a bean for that service and then when the server starts up I can get the instance of the service inside my facade. 想象一下,我有一个依赖于服务的Facade,在Spring中我可以为该服务定义一个bean,然后在服务器启动时就可以在Facade中获取该服务的实例。

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

Assume that service has a concrete implementation and in Spring will automatically inject it. 假设该服务具有具体的实现,并且在Spring中将自动注入它。

Does Guice has a similar approach? Guice有类似的方法吗? can I do something like 我可以做类似的事情吗

class Facade{
  @Inject Service service;
}

or is it a magic that only spring does? 还是只有春天才有的魔力?

In my web application, I am starting embedded tomcat and I used google guice modules in such a way 在我的Web应用程序中,我正在启动嵌入式tomcat,并且以这种方式使用了google guice模块

Guice.createInjector(new ConfigurationModule());

hoping that this will be enough to "inject" whatever is annotated with @Inject . 希望这足以“注入”使用@Inject注释的内容。

However, it is not working ( I am not surprised ). 但是,它不起作用(我不感到惊讶)。 Can you guys help me to figure out which are the BP to inject dependencies on my Servlets or Facades etc..? 你们能帮我弄清楚哪个BP注入对我的Servlet或Facades等的依赖吗?

In Guice, there is no direct equivalent of the @Autowired Spring annotation. 在Guice中,没有@Autowired Spring注释的直接等效项。 Dependency injection usage is explained in the Getting started page . 入门”页中说明了依赖项注入的用法。

1) You have to annotate the constructor of your service with the @Inject annotation: 1)您必须使用@Inject注释来注释服务的构造函数:

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

2) Then define the bindings between types and implementations in a module: 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) And finally build an injector and use it: 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);
    ...
  }

Yes, @Inject can act as @Autowired ... given some conditions. 是的,在某些条件下,@ @Inject可以充当@Autowired ...。

Guice doesn't require Module s, though they're very often used. Guice不需要Module ,尽管它们很常用。 So you can get rid of them if you want to. 因此,您可以根据需要摆脱它们。

If your class is a concrete class, you can directly @Inject it, just like @Autowired , but you also probably have to mark the class @Singleton because the default scope in Guice is not singleton, but a new instance everyone, unlike Spring. 如果您的类是具体的类,则可以直接@Inject ,就像@Autowired一样,但是您可能还必须标记类@Singleton因为Guice中的默认作用域不是单例,而是每个实例的新实例,与Spring不同。

Guice is not Spring, but the most important features of one are present in the other. Guice不是Spring,但是其中一个的最重要的特征存在于另一个中。

Using Guice with Tomcat 将Guice与Tomcat一起使用

When you want to use Guice with Tomcat, there is very little configuration to do, but there is still configuration. 当您想将Guice与Tomcat一起使用时,几乎不需要进行任何配置,但是仍然需要进行配置。 You will require a Module , but only the servlet. 您将需要一个Module ,但只需要servlet。

In your web.xml , add the following: 在您的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"));
  }
}

Now you have a choice with MyService : either you make an interface out of it and you have to define, and bind an implementation, or you make a concrete class out of it. 现在,您可以选择MyService :要么用它创建一个接口,然后定义,绑定一个实现,要么用它创建一个具体的类。

MyService as an interface 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 + "!"; }
}

If you want to avoid the @ImplementedBy , you can still use your module above, and add bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON); 如果要避免使用@ImplementedBy ,仍可以使用上面的模块,并在bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON);添加bind(MyService.class).to(MyServiceImpl.class).in(Scopes.SINGLETON); , or write a provider method in the same Module : ,或在同一Module编写提供者方法:

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

MyService as a concrete class 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 + "!"; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM