我正在使用Spring和Hibernate创建一个Web应用程序。
假设有多个用户想要注册。我将创建一个注册Bean(原型或请求或会话作用域),并在Controller中自动装配它。
现在,我将此Bean传递给Registration Service(带有“@transactional”注释),该服务也在控制器中自动链接。此服务将接收到的注册Bean对象传递给DAO(此DAO在服务中进行了自动链接)。如果服务和DAO是单例模式,那么对于多个用户,请求不会混杂吗?
这是我的做法:我将服务和DAO的范围设置为“请求”。
这样做是否正确?还是我应该采取其他措施使服务和DAO成为“单例模式”呢?
我选择请求作用域的逻辑如下:
将服务和DAO设置为请求作用域的原因是,如果多个用户同时从控制器调用registerationService.registerUser(bean); 并且范围是单例模式,则会存在不一致性,因为一个对象的方法会被不同的输入调用。
请告诉我哪里出错了。
注册Bean
@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>{
}