私は春、冬眠を使用してWebアプリケーションを作成しています。 複数のユーザーが登録したいと仮定します。登録Bean(プロトタイプまたは要求またはセッションスコープ)を作成し、Controllerでautowireします。Spring Webアプリケーションのコントローラ、サービス、リポジトリの範囲?
このBeanは、登録サービス(「@transactional」アノテーションが付いている)に渡しています。このサービスは、コントロールで自動実行されます。 このサービスは受信した登録BeanオブジェクトをDAOに渡します(このDAOはサービス内で自動実行されます)。サービスとDAOが複数のユーザーのために要求を混同しないなら、
これは私がやったことです:サービスの範囲とDAOを「要求」として作成しました。 これは正しいアプローチですか?サービスやDAOをシェルトンにするために他に何ができるのでしょうか?
リクエストの有効範囲の背後にある: サービスとDAOをリクエストスコープにする理由は、複数のユーザーがコールする場合です。 registerationService.registerUser(bean);スコープがシングルトンであれば、そこには一貫性がありません。オブジェクトのメソッドが異なる入力で呼び出されます。
私は間違っていると知っています。
Registeration豆
@Component(value="registerBean")
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "request")
public class RegisterBean {
@NotNull
private String userName;
private String lastName;
@NotNull
private String firstName;
String email_address;
String password;
String confirmPassword;
String gender;
//getters and setters
}
コントローラ
package com.ClickToShop.controllers;
@Controller
@SessionAttributes("user_info")
public class LoginPageController {
RegisterBean registerBean;//used
RegisterationService registerationService;//used
@Autowired
@Qualifier("registerationService")
public void setRegisterationService(RegisterationService registerationService) {
this.registerationService = registerationService;
}
@Autowired
@Qualifier("registerBean")
public void setRegisterBean(RegisterBean registerBean) {
this.registerBean = registerBean;
}
@ModelAttribute(value = "registerBean")
RegisterBean returnModelAttribute() {
return registerBean;
}
@RequestMapping(value = "/login-page.html")
public String showLoginPage() {
System.out.println("Showing login page");
System.out.println(registerBean);
return "login-page";
}
@RequestMapping(value = "/newuser-register", method = RequestMethod.POST)
public String registernewuser(@ModelAttribute("registerBean") @Valid RegisterBean bean, BindingResult result,final RedirectAttributes redirectAttr)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
//some validation code
registerationService.registerUser(bean);
return "redirect:successRegisteration";
}
}
}
Service Layer
@Service("registerationService")
@Transactional
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS,value="request")
public class UserServiceImpl implements RegisterationService {
private User_Details_Pojo userToRegisterPojo;
private AbstractHibernateDAO UserDAO;
@Autowired
public void setUserDAO(AbstractHibernateDAO userDAO) {
UserDAO = userDAO;
}
@Autowired
@Qualifier("userToRegisterPojo")
public void setUserToRegisterPojo(User_Details_Pojo userToRegisterPojo) {
this.userToRegisterPojo = userToRegisterPojo;
}
//main implementation code starts here
@Override
public void registerUser(Object userBean) {
RegisterBean bean=(RegisterBean) userBean;
//bean or model is converted to pojo
UserDAO.save(userToRegisterPojo);//calling DAO with specified pojo
}
}
DAO:
public abstract class AbstractHibernateDAO<T extends Serializable> {
public Class<T> clazz;//class object reference
protected SessionFactory mysessionFactory;
@Autowired
public void setMysessionFactory(SessionFactory mysessionFactory) {
this.mysessionFactory = mysessionFactory;
}
public T findOneByName(final String name){
return (T) getCurrentSession().createQuery("from "+clazz.getName()).uniqueResult();
}
public void setClazz(final Class<T> clazzToSet) {
this.clazz = clazzToSet;
}
public T findOne(final Long id) {
return (T) getCurrentSession().get(clazz, id);
}
@SuppressWarnings("unchecked")
public List<T> findAll() {
return getCurrentSession().createQuery("from " + clazz.getName()).list();
}
public void save(final T entity) {
getCurrentSession().merge(entity);
}
public void update(final T entity) {
getCurrentSession().update(entity);
}
public void delete(final T entity) {
getCurrentSession().delete(entity);
}
public void deleteById(final Long entityId) {
final T entity = findOne(entityId);
delete(entity);
}
protected Session getCurrentSession() {
return mysessionFactory.getCurrentSession();
}
}
コンクリートDAO
@Repository
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS,value="request")
public class UserDAO extends AbstractHibernateDAO<User_Details_Pojo>{
}
複数のユーザーが登録したいと仮定します。すべてのユーザーに対して登録Bean(プロトタイプ、リクエスト、セッションスコープ)を作成します。このBeanを登録サービスに渡します(「@トランスクリプト」注釈付き)。 DAOに登録Beanオブジェクトを追加する必要があります。サービスとDAOが複数のユーザーにリクエストを混在させることはありませんか? – beinghuman
DAOで自分自身でHibernateセッションを管理しようとしている場合を除き、これは起こりません。 SpringはスレッドごとにHibernateセッションを含むトランザクションコンテキストを割り当てます。 Webサーバーは、各ユーザーの要求ごとに、プールからスレッドを取得/取得します。したがって、2人のユーザーからの登録Beanは別々のメモリ位置に「生きて」おり、別々のHibernateセッションを介して処理され、別々のDB接続上の別々のトランザクションでデータベースに書き込まれます。 – Olaf
これは私があなたにこのことを説明することができるかどうかを明らかにするでしょう。複数の要求が来ます.Webサーバは、各request.theseスレッドごとに別個のスレッドを割り当てます。registerbeanをプロトタイプした同じシングルトンコントローラを使用します。シングルトンコントローラがプロトタイプのBeanを使用する場合、このシングルトンコントローラの初期化中に、その依存するPrototype Beanも作成されます。すべてのリクエストが単一のBeanにアクセスします。私を教えてください。 – beinghuman