我正在尝试使用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等的依赖吗??
答案 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,但是其中一个的最重要的特征存在于另一个。
当您想将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 + "!"; }
}