6

Wicket + Spring を統合したいアプリケーションを作成しています。アプリケーションは、ユーザーが来て何かを購入する食料品店です。これを行うには2つの方法があることを知っています。

  1. 注釈アプローチの使用。Wicket-Spring の統合では、Spring Bean を Wicket ページに注入するさまざまな方法を示しています。

    public class FormPage extends WebPage
    {
      @SpringBean
      private IContact icontact;
      ...
      Form<Object> form = new Form<Object>("contactForm",
         new CompoundPropertyModel<Object>(contact))
      {
        private static final long serialVersionUID = 1L;
    
        protected void onSubmit(Contact contact)
        {               
          icontact.saveContact(contact);
        }
      }; 
    
  2. @SpringBean はもちろん有効であり、多くの人がベスト プラクティスと見なしています。しかし、Wicket アプリケーションが必要なサービスを提供する別のアプローチもあります。

    public class YourWicketApp extends WebApplication{
      public static YourWicketApp get(){
        return (YourWicketApp) Application.get();
      }
      private ServiceA serviceA;
      // getter and setter for serviceA here
    }
    

    コンポーネントで、呼び出します

    YourWicketApp.get().getServiceA();

スプリングとウィケットを統合する最良の方法と、それぞれの場合の欠点を知りたい.

ただし、私が覚えている限り、Wicket ページとコンポーネントは Spring コンテナーによって管理されていないため、それらに @Transactional アノテーションを使用することはできません (これはとにかく悪い考えです - トランザクションはより深いレベルに属します)。 この声明は有効ですか?

4

1 に答える 1

7

さまざまなオプションには、特定の利点と欠点があります。ここでは、さまざまなオプションについて説明します。個人的には、アノテーション ベースのアプローチを好みます。アノテーションが付けられたフィールドの適切な切り離しが保証され、コンポーネントのアプリケーション オブジェクトへの依存が減るからです。

1.使用@SpringBean

@SpringBean注釈はいいですね。これでマークされたフィールドは、コンポーネントでシリアル化されないことが保証されています。つまり、Wicket フレームワークは、デタッチ サイクルごとにフィールドを無効にすることで Bean を「管理」するので、心配する必要はありません。

でマークされたフィールドは、@SpringBeanいつでもモックに置き換えることができるため、簡単にテストできます。Wicket には、ApplicationContextMockWicketTester を使用するときに Bean が注入されるクラスもあります。

MyComponent.java

public class MyComponent extends Panel {
    @SpringBean
    MyServiceA myServiceA;
}

MyComponentTest.java 内

final ApplicationContextMock appContext = new ApplicationContextMock();
appContext.putBean(mock(MyServiceA.class));
Application app = new Application() {
    public void init() {
        ...
        getComponentInstantiationListeners().add(new SpringComponentInjector(this, appContext));
    }
}
WicketTester wicketTester = new WicketTester(app);
wicketTester.startComponent(MyComponent.class);

2.使用YourWicketApp.get().getServiceA()

これは、Spring を Web アプリケーションにバインドする必要がないため、非常に軽量なアプローチです。大規模なアプリケーションを構築していない場合、これは実行可能な代替手段になる可能性があります。

このアプローチの主な欠点は、テスト容易性が低いことです。アプリケーションに静的にアクセスしているため、テストでアプリケーションを簡単に置き換えることはできません。もちろん、 をYourWicketAppForTests拡張するアプリケーションを作成できYourWicketAppますが、常にそのアプリケーションに制限されます。これにより、各サービス依存コンポーネントからアプリケーション クラスへの依存関係が作成されます。さらに、サービス クラスごとにメソッドが必要になるため、アプリケーション クラスが煩雑になります (通常、最初は短すぎません)。

3.@Transactional

トランザクションは間違いなく Wicket ページに属しておらず、サービス レイヤーで処理する必要があります。Bean のインジェクションとコンポーネントのインスタンス化を処理しているのは Spring ではなく Wicket であるため、@Transactional私が正しければ、とにかくアノテーションは機能しません。

于 2012-12-27T13:19:20.220 に答える