3

現在、JSF 2 と Spring 3 AOP の組み合わせを使用して問題に直面しています。

アプリケーションは、従来の 3 層アーキテクチャ (Web、サービス、データベース) として設計されています。したがって、Spring 管理の JSF-Bean は、ビジネス ロジックを表すサービス Bean を呼び出します。

マネージド Bean は次のようになります。

@Named("startPage")
@Scope("view")
public class ManagedBean implements Serializable {

    @Inject
    private  ServiceBeanA serviceBeanA;

    public void someMethod() {
        serviceBean.doSomeBusinessLogic();
}

この Bean はビュー スコープであるため、Serializeable を実装し、インスタンス変数 (この場合は ServiceBeanA) も実装します ( JSF バッキング Bean はシリアル化できる必要がありますか?

これまでのところ、すべてが期待どおりに機能しています。

ここで、ビジネス サービスで宣言されたビジネス メソッドの呼び出しをインターセプトしたいと考えています。そこで、いくつかの基本的なロギングを行うアスペクトを作成し、Spring 構成で宣言しました。

<bean id="aspectLogging" class="my.package.AspectLogging" />

<aop:config>
    <aop:aspect ref="aspectLogging">
        <aop:pointcut id="serviceMethodInvocation" expression="execution(*  my.services.ServiceBeanA.doSomeBusinessLogic())" />
        <aop:around pointcut-ref="serviceMethodInvocation" method="performLogging" />
    </aop:aspect>
</aop:config>

アスペクト:

public class AspectLogging {

    public Object performLogging(ProceedingJoinPoint pjp) throws Throwable {

        Object toReturn = null;        
        System.out.println(">>>>"+ pjp.getSignature().toLongString());
        toReturn = pjp.proceed();
        return toReturn;
    }
}

そして今、問題が発生します:

SCHWERWIEGEND: Exiting serializeView - Could not serialize state:        org.springframework.aop.aspectj.AspectJPointcutAdvisor
java.io.NotSerializableException: org.springframework.aop.aspectj.AspectJPointcutAdvisor

Springsource で 2 つの同一の問題の説明を見つけました (残念ながら解決されていません)。

http://forum.springsource.org/showthread.php?87428-AspectJPointcutAdvisor-not-Serializable http://forum.springsource.org/archive/index.php/t-57602.html

もちろん、Aspect Orientation を使用することはできませんが、他のサードパーティのライブラリ パーティでも同じ問題が発生する可能性があります。

私がしたことは、ビジネス サービスを保持するインスタンス変数を一時的としてマークすることでした。

public class ManagedBean implements Serializable {

    @Inject
    private  transient ServiceBeanA serviceBeanA;

    public void someMethod() {
     serviceBean.doSomeBusinessLogic();
    }

これは、セッションが復元 (デシリアライズ) されるまで正常に機能します。もちろん、逆シリアル化後、変数 (serviceBeanA) は null です。セッションをシリアル化しないように Web コンテナー (Tomcat など) を構成することもできますが、このアプリケーションはクラウドで実行されるため、サーバーの構成は担当しません。

私が持っていた唯一のアイデアは、提供することによって基本的なJavaシリアライゼーション機能を使用することでした

private synchronized void readObject(ObjectInputStream s) throws IOException,    ClassNotFoundException 

private synchronized void writeObject(ObjectOutputStream s) throws IOException

マネージド Bean のメソッド。

private synchronized void readObject(ObjectInputStream s) throws IOException,    ClassNotFoundException {
    s.defaultReadObject();
    ApplicationContext context = new ClassPathXmlApplicationContext("services.spring-config.xml", "database.spring-config.xml");
    this.ServiceBeanA = (ServiceBeanA) context.getBean("serviceBeanA");
}

private synchronized void writeObject(ObjectOutputStream s) throws IOException {
    s.defaultWriteObject();
}

このソリューションは機能しますが、非常に不器用で洗練されていないソリューションのようです。サービス Bean を使用するすべてのマネージド Bean で、ほぼ同じコードを繰り返さなければなりません。さらに、管理対象 Bean は、Springs アプリケーション コンテキストをインポートしてサービス変数を復元するため、このように Spring に緊密に結合されます。

誰かがより良いアーキテクチャのアプローチを考えられますか? 前もって感謝します!

4

0 に答える 0