2012-02-24 53 views
0

我是新來Guice和已經陷入:)Guice3辛格爾頓永遠不會在GAE項目實例

我幾乎複製類GuiceConfig,OfyFactory和Motomapia project稍微修改OFY(你可以瀏覽),用它爲s樣品。

我創建GuiceServletContextListener它看起來像這樣

public class GuiceConfig extends GuiceServletContextListener 
{ 
    static class CourierServletModule extends ServletModule 
    { 
     @Override 
     protected void configureServlets() 
     { 
      filter("/*").through(AsyncCacheFilter.class); 
     } 
    } 

    public static class CourierModule extends AbstractModule 
    { 
     @Override 
     protected void configure() 
     { 
      // External things that don't have Guice annotations 
      bind(AsyncCacheFilter.class).in(Singleton.class); 
     } 

     @Provides 
     @RequestScoped 
     Ofy provideOfy(OfyFactory fact) 
     { 
      return fact.begin(); 
     } 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent servletContextEvent) 
    { 
     super.contextInitialized(servletContextEvent); 
    } 

    @Override 
    protected Injector getInjector() 
    { 
     return Guice.createInjector(new CourierServletModule(), new CourierModule()); 
    } 
} 

我加入這個監聽到我的web.xml

<web-app> 
    <listener> 
     <listener-class>com.mine.courierApp.server.GuiceConfig</listener-class> 
    </listener> 

    <!-- GUICE --> 
    <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> 
     <dispatcher>REQUEST</dispatcher> 
     <dispatcher>FORWARD</dispatcher> 
     <dispatcher>INCLUDE</dispatcher> 
    </filter-mapping> 

    <!-- My test servlet --> 
    <servlet> 
     <servlet-name>TestServlet</servlet-name> 
     <servlet-class>com.mine.courierApp.server.TestServlet</servlet-class> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>TestServlet</servlet-name> 
     <url-pattern>/test</url-pattern> 
    </servlet-mapping> 
</web-app> 

OfyFactory看起來像這樣

@Singleton 
public class OfyFactory extends ObjectifyFactory 
{ 
    Injector injector; 

    @Inject 
    public OfyFactory(Injector injector) 
    { 
     this.injector = injector; 

     register(Pizza.class); 
     register(Ingredient.class); 
    } 

    @Override 
    public <T> T construct(Class<T> type) 
    { 
     return injector.getInstance(type); 
    } 

    @Override 
    public Ofy begin() 
    { 
     return new Ofy(super.begin()); 
    } 
} 

OFY沒有任何Guice標註...

public class Ofy extends ObjectifyWrapper<Ofy, OfyFactory> 
{ 
    // bunch of helper methods here 
} 

最後在那裏我試圖用注入外場測試的servlet看起來像這樣

public class TestServlet extends HttpServlet 
{ 
    @Inject Ofy ofy; 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    { 
     ofy.save(new Pizza()); 
    } 
} 

OFY OFY總是空。它從未被注入。而且它沒有被注入,因爲OfyFactory從未被實例化,其構造函數從未被調用過。

你能指出我做錯了什麼嗎?爲什麼我的單身永遠不會被創建?

非常感謝。

回答

4

而是在web.xml文件中定義TestServlet,儘量從web.xml中刪除它的映射,並在configureServlets()方法加入這一行:

serve("/test").with(TestServlet.class); 

您可能還需要綁定TestServlet作爲Singleton要麼通過用@Singleton註釋的類或通過添加

bind(TestServlet.class).in(Singleton.class); 

線到模塊中的一個。

發生了什麼是Guice實際上並沒有創建您的servlet,因此它無法注入Ofy對象。 Guice只會在使用serve(...).with(...)綁定的指示下創建servlet。在web.xml中定義的任何servlet都不在Guice的控制範圍之內。

+0

你是對的。在我發佈這個問題之後,我完成了你寫的內容。現在我得到'自定義提供程序中的錯誤,com.google.inject.OutOfScopeException:無法訪問作用域對象。我們目前不在HTTP Servlet請求中,或者您可能忘記將com.google.inject.servlet.GuiceFilter作爲該請求的servlet過濾器。如果我從提供程序中刪除'@ RequestScoped',它將起作用。可能是什麼問題呢? – expert 2012-02-24 04:05:30

+1

由於'TestServlet'必須是單例,因此如果'Ofy'對象需要根據請求作用域,即'@ RequestScoped',您需要將'Provider '注入'TestServlet'。 http://code.google.com/p/google-guice/wiki/ServletModule上的文檔很好地解釋了這一點。 – 2012-02-24 04:15:07

+0

它幫助!並且對我沒有閱讀文檔感到羞恥:) – expert 2012-02-24 04:27:44