0

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

我几乎从Motomapia 项目(您可以浏览)中复制了 GuiceConfig、OfyFactory 类并稍微修改了 Ofy,并将其用作示例。

我创建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

1 回答 1

4

Instead of defining TestServlet in the web.xml file, try deleting its mapping from web.xml and adding this line in the configureServlets() method:

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

You may also need to bind TestServlet as a Singleton either by annotating the class with @Singleton or by adding a

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

line to one of the modules.

What's happening is that Guice is not actually creating your servlet so it isn't able to inject the Ofy object. Guice will only create servlets if it is instructed to do so using a serve(...).with(...) binding. Any servlets defined in the web.xml are outside of Guice's control.

于 2012-02-24T03:58:35.627 回答