2

私のSpringプロジェクトには、Springによって管理されるJMSメッセージリスナーがあります。

<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory" p:brokerURL="tcp://localhost:61616"/>

<bean id="simpleExampleListener" class="my.package.ExampleListener" />

<jms:listener-container container-type="default" connection-factory="jmsFactory" acknowledge="auto" concurrency="1-3">
    <jms:listener destination="TEST.FOO" ref="simpleExampleListener" method="onMessage"/>
</jms:listener-container>

ある特定のメッセージで、リクエストスコープのSpring MVCコントローラーを呼び出す必要があります(実際の目標は、リクエストスコープでコントローラーによって呼び出されるサービスを呼び出すことです)。したがって、Springが必要に応じてそれらを管理し、スコープにバインドされていないため、リスナーから直接それを行うことはできません(そのため、@Autowireまたはを介してコントローラーにアクセスできませんApplicationContext)。解決策の1つは、コントローラーによってマップされたRESTテンプレートからURLへのHTTP呼び出しである可能性があります。しかし、私はその種のオーバーヘッドだと思います。それで、HTTPプロトコルのオーバーヘッドを回避し、Spring MVCフレームワーク内でControllerを呼び出す他の方法があるのではないでしょうか?

4

1 に答える 1

2

サービスクラスがrequest-scopeとして定義されている理由を疑問視する必要があります。理想的には、サービスレイヤーがWebレイヤーに暗黙的/明示的に依存してはなりません。それが制御できない場合は、次の回避策を使用できます。依存関係としてspring-test.jarを追加する必要があります。

    class Listener {

    @Autowired
    RequestScopedService requestScopedService;


    void handle() {
        MockHttpServletRequest request = new MockHttpServletRequest();
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
        try {
             requestScopedService.callSomeMethod();
        } finally {
             ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
             RequestContextHolder.resetRequestAttributes();
        }

サービスBeanが<aop:scoped-proxy/>タグで構成されている場合は、自動配線できます。それ以外の場合は、(ApplicationContextAwareを実装して)アプリケーションコンテキストを取得し、ルックアップを実行する必要があります。

于 2012-05-11T17:03:06.823 に答える