0

クライアントとしてフレックスを備えたグラスフィッシュ/ウェブスフィアでスプリングmvcを使用しています。Web サービスの 1 つはクライアントに指示を返す必要があり、その後は何も返さずに非同期で実行を継続します。

純粋な Java スレッドを使用しようとしましたが、Spring が Web アプリケーション コンテキストにアクセスできなかったため、機能しませんでした。

次に、「春の方法」( @async + を使用)でスレッドを使用しようとしましたが、春は例外をスローしました:

12-11-2013 16:11:44,769 [SimpleAsyncTaskExecutor-1] エラー com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService.handleCRMEventsSending(行: 254)[ userrrr | 30605808 | 2c90908b424ca07a01424ca374c00000 ] - [アンケート ID: 2c90908b424ca07a01424ca374c00000] の sendCrmEvent 要求が例外で失敗しました: 名前 'scopedTarget.sessionCachedUserMetadata' を持つ Bean の作成中にエラーが発生しました: スコープ 'session' は現在のスレッドに対してアクティブではありません。シングルトンから参照する場合は、この Bean のスコープ付きプロキシを定義することを検討してください。ネストされた例外は java.lang.IllegalStateException: No thread-bound request found: 実際の Web リクエスト以外のリクエスト属性を参照していますか? または、最初に受信したスレッドの外でリクエストを処理しますか? 実際に Web リクエスト内で操作していてもこのメッセージが表示される場合、コードは DispatcherServlet/DispatcherPortlet の外部で実行されている可能性があります。この場合、RequestContextListener または RequestContextFilter を使用して現在のリクエストを公開します。(10065) com.app.questionnaire.exceptions.CRMEventException: [アンケート ID: 2c90908b424ca07a01424ca374c00000] の sendCrmEvent 要求が例外で失敗しました: 名前 'scopedTarget.sessionCachedUserMetadata' を持つ Bean の作成中にエラーが発生しました: スコープ 'session' は現在のスレッドに対してアクティブではありません。シングルトンから参照する場合は、この Bean のスコープ付きプロキシを定義することを検討してください。ネストされた例外は java.lang.IllegalStateException: No thread-bound request found: 実際の Web リクエストの外部でリクエスト属性を参照していますか、または元の受信スレッドの外部でリクエストを処理していますか? 実際に Web リクエスト内で操作していてもこのメッセージが表示される場合、コードは DispatcherServlet/DispatcherPortlet の外部で実行されている可能性があります。この場合、RequestContextListener または RequestContextFilter を使用して現在のリクエストを公開します。com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService.handleCRMEventsLogics(CloseQuestionnaireBusinessActionsService.java:780) com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService.handleCRMEventsSending(CloseQuestionnaireBusinessActionsService.java:251) com.app.closeQuestionnaire.logic.CloseQuestionnaireBusinessActionsService$$ net.sf の FastClassByCGLIB$$729836cc.invoke()。

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
    version="2.5">

    <display-name>advisor-server</display-name>

    <!-- ========= Context parameters ========= -->

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:ApplicationContext.xml</param-value>
    </context-param>

    <context-param>
        <description>Parameter specifying the location of the log4j
            configuration file</description>
        <param-name>log4jConfigLocation</param-name>
        <param-value>file:${advisorLog4jConfigLocation}</param-value>
    </context-param>

    <!-- ========= Listeners ========= -->

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>

    <listener>
        <display-name>serviceRefRegistrar</display-name>
        <listener-class>com.app.application.ServiceRefRegistrar
        </listener-class>
    </listener>

    <!-- Loads configuration to make sure we don't crash during runtime in case 
        of parsing errors -->
    <listener>
        <listener-class>com.app.application.ApplicationConfigListener
        </listener-class>
    </listener>

    <!-- ========= filters ========= -->

    <filter>
            <filter-name>requestContextFilter</filter-name>
            <filter-class>org.springframework.web.filter.RequestContextFilter
            </filter-class>
    </filter>
    <filter-mapping>
            <filter-name>requestContextFilter</filter-name>
            <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>LoggingFilter</filter-name>
        <filter-class>com.app.general.logging.LoggingFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>LoggingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>AdviserRequestFilter</filter-name>
        <filter-class>com.app.commons.application.AdviserRequestFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>AdviserRequestFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



</web-app>

spring.xml

<beans >

    <!-- Context -->
    <context:component-scan base-package="com.modelity.advisor" />
    <tx:annotation-driven transaction-manager="transactionManager" />


    <!-- Activates @Scheduled and @Async annotations for scheduling -->  
    <task:annotation-driven />


</beans>


@Component
public class PostClosePreformerProcess{

    @Autowired
    private QuestionnaireBusinessService questionnaireService;

    public PostClosePreformerProcess() {

    }


    @Async
    public void doClose(String questionnaireId) {
        try {
            questionnaireService.postCloseQuestionnaire(questionnaireId);
        } catch (Exception e) {
            AdvisorLogger.error(this, "Post Closed Failed", e.getMessage(), e);
        }
    }


    public QuestionnaireBusinessService getQuestionnaireService() {
        return questionnaireService;
    }


    public void setQuestionnaireService(
            QuestionnaireBusinessService questionnaireService) {
        this.questionnaireService = questionnaireService;
    }
}




@Service
public class CloseQuestionnaireBusinessService {

    @Autowired
    private PostClosePreformerProcess postClosePreformerProcess;

    public PreCloseQuestionnaireDto preCloseQuestionnaire(String questionnaireId) {

                postClosePreformerProcess.doClose(questionnaireId);
}
}

編集:実際、非同期(スレッド)部分は、セッションのスコープで定義されたアプリケーション内のBeanを使用する必要があるため、セッション/リクエストスコープにとどまる必要があります(これは、例外が不平を言うものです):

@Component("sessionCachedUserMetadata")
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Lazy(true)
public class UserMetadataSessionCachedService implements UserMetadataBusinessService {
4

0 に答える 0