0

私は春のWebアプリケーションに取り組んでいます。アプリケーションはプロパティ ファイルで構成されます。異なるサーバーにアプリケーションの複数のインスタンスがあり、各インスタンスには異なる構成ファイルがあります (各インスタンスは異なる顧客用にカスタマイズされています) 私はコントローラーとサービスを使用しています。このようなもの:

public class Controller1 {
    @Autowired
    Service1 service1;

    @RequestMapping(value = "/page.htm", method = { RequestMethod.GET, RequestMethod.POST })
    public ModelAndView serve(HttpServletRequest request, HttpServletResponse response) {
        service1.doSomething();
        return new ModelAndView("/something");
    }
}

@Service
public class Service1 {
    @Autowired
    Service2 service2;
    public void doSomething () {
            …
            service2.doAnotherThing();
            …
        }
}

@Service
public class Service2 {
    @Value("${propertyValue}")
    private String propertyValue;

    //doAnotherThing()  will use propertyValue
    public void doAnotherThing () {
        …
        //Do something with propertyValue
        …
        }
}

今、私には新しい要件があります。顧客ごとに複数のインスタンスはありませんが、すべての顧客に対して複数のドメインを持つインスタンスは 1 つだけです。アプリケーションは、コントローラー内の要求オブジェクトのホスト名に応じて構成を決定する必要があります。したがって、顧客がブラウザで www.app1.com を指定する場合は構成ファイル 1 を使用する必要がありますが、顧客が www.app2.com を使用する場合は構成 2 を使用する必要があります。

構成ファイルをデータベースに移動しましたが、依存性注入の方法がわからないことに気付きました。サービスはリンクされており、service1 は service2 を使用し、service2 は構成に依存する値を使用する必要があります。サービス 2 には、要求オブジェクトに関する知識がありません。

これを解決するきれいな方法はありますか?

ありがとう、

4

1 に答える 1

1

1 つのアプローチは、Spring 構成のシングルトンとしてすべての顧客の構成オブジェクトを作成することです。

<bean id="customerAConfig"../>
<bean id="customerBConfig"../>
<bean id="customerCConfig"../>

また、configuartion がアクティブなポインターとして機能する、セッション スコープの ConfigurationService を用意します。

public class ConfigurationService {

   private CustomerConfig activeConfig;

   // getters & setters..
}

シングルトン コンポーネントに挿入できるように、Spring 構成でこのサービスのシングルトン プロキシを構成します。プロキシを作成するには、Spring のクラスパスに cglib が必要です。

<bean class="com.mycompany.ConfigurationService" scope="session">
  <aop:scoped-proxy/>
</bean>

ログインコントローラーで、仮想ホスト名で使用する構成を選択し、後で取得できるように ConfigurationService に保存します (ConfigurationService はセッションスコープであることを思い出してください)。

public class LoginController {

  @Autowired private CustomerConfig[] custConfigs;
  @Autowired private ConfigurationService configService;

  @RequestMapping(method = POST)
  public String login(HttpServletRequest request, ..) {
    ...
    String host = request.getServerName();
    CustomerConfig activeConfig = // decide which one based on host..
    configService.setActiveConfig(activeConfig);
    ...
  }
}

以下は、顧客固有の構成を読み取るサンプル FooController です。

@Controller
@RequestMapping("/foo")
public class FooController {

  @Autowired private ConfigurationService configService;

  @RequestMapping(method = "GET")
  public String get() {
    ...
    CustomerConfig config = configService.getActiveConfig();
    ...
  }

  ...
}

プログラムにログイン ページのような単一のエントリ ポイントがない場合は、同様のロジックをフィルターとしてコーディングできます。セッションにアクティブな構成が設定されているかどうかを確認し、そうでない場合はホスト名に基づいて検索します

于 2013-07-24T05:33:55.430 に答える