Guice3 Singleton从未在GAE项目中实例化

时间:2012-02-24 03:09:23

标签: java google-app-engine guice guice-3

我是Guice的新手,已经卡住了。)

我几乎将类GuiceConfig,OfyFactory和稍微修改过的Ofy从Motomapia project(你可以浏览)复制出来,用它作为样本。

我创建了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从未实例化,它的构造函数永远不会被调用。

你能指出我做错了什么吗?为什么我的单身人士永远不会被创造?

非常感谢。

1 个答案:

答案 0 :(得分: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的控制之下。