3

さて、私はMVCSpring3デザインで作成されたController->Service->Repositoryから3つのレイヤーを持っています。さて、私の質問は、デフォルトのスコープがシングルトンとして定義されているので、それらはスレッドセーフですか?

コードは次のようになります。

UserController.java

@Controller
@RequestMapping("/users")
public class UserController extends ExceptionExtension {
     @Autowired
     private IUserService userService;

     @RequestMapping(value = { "/update", "/update/" }, method = RequestMethod.GET)
     public String updateUser(@RequestParam("email") String eMail, ModelMap model)
        throws Exception {

          if (eMail.isEmpty() || eMail == null) {
              throw new ArgumentIsEmptyException("Required String parameter 'email' is empty");
          } else {
              UserModel userModel = userService.setUser(eMail);

              if (userModel != null) {
                  model.put("roleList", userService.setRoleList());
                  model.put("title", "Update Existing User");
                  model.put("post", "/users/post/update");
                  model.put("userForm", userModel);

                  return "users.update";
              } else {
                  model.put("title", "Update Existing User");
                  model.put("result", "<font color='red'><u>" + eMail + "</u> does not exist in the database.</font>");
                  model.put("flag", "Error");

                  return "users.result";
              }
          }
     }
}

UserService.java

public class UserService implements IUserService {

    @Autowired
    private IUserManager userManager;

    public UserModel setUser(String eMail) {
        UserModel userModel = new UserModel();
        Entity userEntity = userManager.getUser(eMail);

        if (userEntity != null) {
            userModel.setEMail(eMail);
            userModel.setRole(userEntity.getProperty("role").toString());
            userModel.setEnable((Boolean)userEntity.getProperty("enable"));

            return userModel;
        } else {
            return null;
        }
    }
}

たとえば、ユーザーAとユーザーBが同じURLを同時に実行しているが、パラメーターが異なるとします。
ユーザーリクエスト=>「http://domain.com/users/update?user=myname1@domain.com」。
ユーザーBのリクエスト=>「http://domain.com/users/update?user=myname2@domain.com」。

コントローラはシングルトンであるため、ユーザーAの電子メール変数はユーザーBの電子メール変数とオーバーラップし、その逆も同様ですか?

このシナリオでシングルトンスレッドセーフがどのように機能するかを理解するのは難しいと感じています。@Serviceと@Repositoryを@Scope( "prototype)として宣言して、内部メソッド変数を新しいインスタンスから分離する必要がありますか?

====>

@ServiceレイヤーへのScope( "request")で、このエラーメッセージが表示されました:/

3328 [main]エラーorg.springframework.web.context.ContextLoader-コンテキストの初期化に失敗しましたorg.springframework.beans.factory.BeanCreationException:「roleController」という名前のBeanの作成中にエラーが発生しました:自動配線された依存関係の挿入に失敗しました。ネストされた例外はorg.springframework.beans.factory.BeanCreationExceptionです:フィールドを自動配線できませんでした:private com.company.dashboard.service.IRoleService com.company.dashboard.controller.RoleController.roleService; ネストされた例外はorg.springframework.beans.factory.BeanCreationExceptionです:「roleService」という名前のBeanの作成中にエラーが発生しました:スコープ「request」は現在のスレッドに対してアクティブではありません。シングルトンから参照する場合は、このBeanのスコープ付きプロキシを定義することを検討してください。ネストされた例外はjava.lang.IllegalStateExceptionです。スレッドにバインドされたリクエストが見つかりません:実際のWebリクエストの外部でリクエスト属性を参照していますか、それとも最初に受信したスレッドの外部でリクエストを処理していますか?実際にWebリクエスト内で操作していて、それでもこのメッセージを受信する場合は、コードがDispatcherServlet / DispatcherPortletの外部で実行されている可能性があります。この場合、RequestContextListenerまたはRequestContextFilterを使用して現在のリクエストを公開します。

4

2 に答える 2

1

userServiceここで、スレッドセーフはスコープの場合の内部ロックに依存しますsingleton

これが最終的に発生することです=>同じuserSpaceBeanが両方のリクエストに使用され、両方のリクエストが同時にuserServiceBeanにアクセスします。したがって、IUserService操作全体を適切に実行するには、スレッドセーフである必要があります。

または

スコープをに置きrequestます。

この場合、すべてのリクエストに新しいBeanが割り当てられ、スレッドの制限により、操作全体がスレッドセーフになります。それに応じてコードを提供しましたIUserSpace

于 2012-11-26T16:01:14.527 に答える
0

コメントで提案されているように、レイヤースコープ:プロトタイプを作成する場合は、問題を下のレイヤーに移動するだけです。

トランザクションの境界を設定する場所を決定する必要があります。通常、これはサービスへの呼び出しのレベルで行われます。春はあなたのためにそれを処理することができます。

コントローラ、サービス、およびリポジトリは通常、ステートレスな方法で実装する必要があります。つまり、これらのクラスには、メソッドが変更するインスタンス変数がありません。そうしないと、競合状態に対して脆弱になります。最後に、データストアはトランザクションの使用をサポートする必要があります。

GoogleAppengineデータストアを使用します。他のRDBMSとは異なり、トランザクションに対する非常に特殊なアプローチがあります。Javaアプリからappengineと通信するには、「Objectify」をお勧めします。[その概念について](および基盤となるBigTableデータストア1の概念について)読むことから始めます。

于 2012-11-26T17:25:46.300 に答える