Guice - что является эквивалентом Spring Autowired в Guice - PullRequest
0 голосов
/ 31 октября 2018

Я пытаюсь использовать Guice, и я иду из весны.

Мне интересно, является ли @Inject эквивалентом @Autowired в Spring и могу ли я использовать его в веб-приложении точно так же, как я использую его в Spring.

Представьте, что у меня есть Facade, который зависит от службы, весной я могу определить bean-компонент для этой службы, а затем, когда сервер запускается, я могу получить экземпляр службы внутри своего фасада.

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

Предположим, что сервис имеет конкретную реализацию и в Spring автоматически внедрит его.

Есть ли у Guice аналогичный подход? могу ли я сделать что-то вроде

class Facade{
  @Inject Service service;
}

или это волшебство, которое делает только весна?

В моем веб-приложении я запускаю встроенный tomcat и таким образом использовал модули Google Guice

Guice.createInjector(new ConfigurationModule());

в надежде, что этого будет достаточно, чтобы «впрыснуть» все, что помечено @Inject.

Однако это не работает (я не удивлен). Не могли бы вы, ребята, помочь мне выяснить, какие БП вводят зависимости в мои сервлеты или фасады и т.д ..?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Да, @Inject может действовать как @Autowired ... при определенных условиях.

Guice не требует Module s, хотя они очень часто используются. Так что вы можете избавиться от них, если хотите.

Если ваш класс является конкретным классом, вы можете напрямую @Inject его, точно так же, как @Autowired, но вам также, вероятно, придется пометить класс @Singleton, поскольку область действия по умолчанию в Guice - это не синглтон, а новый экземпляр всем, в отличие от весны.

Guice - это не весна, но самые важные черты одной присутствуют в другой.

Использование Guice с Tomcat

Когда вы хотите использовать Guice с Tomcat, конфигурация выполняется очень мало, но конфигурация все еще существует. Вам потребуется Module, но только сервлет.

В вашем 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 + "!"; }
}
0 голосов
/ 31 октября 2018

В Guice нет прямого эквивалента аннотации @Autowired Spring. Использование внедрения зависимостей объясняется на странице Начало работы .

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