【问题标题】:Google Guice MethodInterceptor under Tomcat 8.5Tomcat 8.5下的Google Guice MethodInterceptor
【发布时间】:2017-08-24 03:49:53
【问题描述】:

在 tomcat 8.5 下,我们不想使用 guice 作为提供者的 aop 方法拦截器。我们目前已经在我们的 Java-FX 应用程序中使用拦截器和 guice,没有任何问题。

尝试在 Tomcat 下做同样的事情是行不通的。对象通过 guice 注入到 servlet 中,但这些对象的注释方法不绑定到拦截器。看起来 guice 可能认为 cglib/asm 不可用并恢复为 none-aop。

为了使用 guice 的 aop,servlet 容器是否需要满足任何特殊的先决条件?如上所述,guice/cglib/asm 的相同配置适用于我们在任何 webapp 项目中。

@Singleton
public class TestServlet extends HttpServlet {

    @Inject
    X                           x;

    public TestServlet() {
        System.out.println("constructor");
        try {
            throw new IOException();
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
        throws ServletException, IOException {
        testMethod(resp);
    }

    protected void testMethod(final HttpServletResponse resp) throws IOException {
        x.test(resp);
    }
}

我们不希望我们的 servlet 中的 X 包含被拦截的方法。 通过将 throw/catch 放在构造函数中,我们验证了构造函数是通过 guice 调用的。

public class X {
    @Y
    public int test(final ServletResponse res) throws IOException {
        res.getWriter().write("123");
        return 1;
    }
}


public class TestInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(final MethodInvocation arg0) throws Throwable {
        System.out.println("METHOD INTERCEPTOR " + arg0);
        return arg0.proceed();
    }
}


public class Module extends AbstractModule {
    @Override
    protected void configure() {
        System.out.println("TestInterceptor configuration");
        bindInterceptor(Matchers.any(), Matchers.annotatedWith(Y.class), new TestInterceptor());
    }
}


@WebListener
public class BootStrap extends GuiceServletContextListener {

...

    @Override
    protected Injector getInjector() {
    final Injector inject = Guice.injector(new Module(), new ServletModule() {
            @Override
            protected void configureServlets() {
                super.configureServlets();
                System.out.println("Injector");
                serve("/test2/*").with(TestServlet.class);
            }
        });
        return inject;
    }
}

servlet 是可访问的,并且 X 不为空,但在调试器中查看它很明显没有进行任何二进制代码修改。

我们在这里遗漏了什么吗?任何人都可以链接一个工作 guice (4+)/tomcat (8+)/aop 示例的示例吗?

编辑

原来它与 servlet 容器无关。问题在于 guice 本身。很抱歉造成混乱,这个问题很难解决。 对于那些感兴趣的人,我们打开了一个问题 https://github.com/google/guice/issues/1094

请注意,在撰写本文时,这不被视为错误。也可能是我们误解了 javadoc。

【问题讨论】:

    标签: java aop guice tomcat8 guice-servlet


    【解决方案1】:

    我之前在 Tomcat 中使用过 Guice AOP(尽管它是 Tomcat 的旧版本)并且 AOP 可以工作。 (我无法链接,因为它是专有代码)。

    我在查看您发布的代码时注意到的一件事是您没有使用 GuiceFilter,我认为这是必需的。

    here 所述,您需要在 web.xml 的顶部配置它,如下所示:

    <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>
    

    基于 cmets 编辑: 您不必修改/破解类加载器即可在 servlet 容器中使用 Guice 拦截器。它们应该开箱即用,无需额外更改。

    【讨论】:

    • 非常感谢您的帮助 :D 不幸的是我已经有了这个设置。当您使用 tomcat 时,您是否通过命令行更改了类加载器或在 server.xml 中设置了类加载器委托?
    • 我们根本没有改变类加载器。
    • 我们解决了。事实证明,问题出在 guice 上,而不是其他问题。这件事相当复杂,所以我稍后会链接这个问题,而不是在这里详细说明。
    • 再次感谢您的帮助。如果您将“Guice Interceptors in a servlet container don't require you to mess with the classloader”之类的东西放入您的回答器中,我会接受它。
    • 已编辑。请务必链接问题,因为我很好奇。
    猜你喜欢
    • 2012-12-07
    • 1970-01-01
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 2019-03-25
    • 2019-10-25
    • 2018-07-28
    相关资源
    最近更新 更多