我正在使用spring,hibernate创建一个Web应用程序。 假设有多个用户想要注册。我将创建一个注册bean(原型或请求或会话作用域)并在Controller中自动装配。
现在我将这个bean传递给注册服务(注释为“@transactional”注释),该注释也在控制器中自动装配。 此服务将收到的注册bean对象传递给DAO(此DAO在服务中自动装配)如果服务和DAO是singelton,请求是否会被多个用户混淆?
以下是我所做的:我已将服务范围和DAO创建为“请求”。 这是正确的方法吗?或者我还能做些什么来制作服务和DAO singelton?
我的请求范围背后的逻辑: 将服务和DAO作为请求作用域的原因是多个用户调用 registerationService.registerUser(豆);从控制器同时和范围是singelton然后将没有一致性因为一个对象的方法被调用不同的输入。
让我知道我错在哪里。
Registeration 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>{
}
答案 0 :(得分:3)
使用@Repository为@Service和Dao类注释您的服务类。
<context:component-scan base-package="x.y.z.service, x.y.z.dao" />
它将自动为您的类创建单例bean
答案 1 :(得分:2)
除非你的DAO需要实例字段,否则它们不需要作为请求作用域。只要用Session
检索你的Hibernate Session#getCurrentSession()
,它是线程绑定的,一个DAO实例来处理所有请求就可以了。这同样适用于服务类和控制器。
至于你的陈述
我认为减慢对用户的响应
这并非总是如此,取决于物体的重量。无论如何,Servlet容器和Spring DispatcherServlet
都实例化了很多对象。你不应该看到一个很大的变化。
创建这些对象的池将是过度的。注意:那些不是线程池,只是对象池。
答案 2 :(得分:2)
服务和DAO应该是无国籍的。这将允许您将它们配置为Spring单例。我希望当你说&#34; singleton&#34;。
时,这就是你的意思所有线程问题,包括线程池,都将由基础架构负责:您的Web / Java EE服务器和Spring DI。
答案 3 :(得分:0)
你应该使用spring注入你的服务,dao对象到你的控制器,默认情况下通过spring注入的所有bean都是单例
答案 4 :(得分:0)
DAO和服务将是单例,因为它们只是方法,不会修改任何其他线程使用的全局变量。他们有自己的堆栈。