Tengo un controlador de registro de usuario:
@Autowired private EmailTools emailTools; @Controller public class RegistrationController { @RequestMapping(value="/registerUser", method=RequestMethod.POST ) public String registerUser(HttpSession session,Model model,User user){ //RegisterUserDetails of scope prototype RegisterUserDetails regUserDetails = appContext.getBean(RegisterUserDetails.class); //rgistering user in db regUserDetails.setUser(user); //sending confirmation email emailTools.SendEmail(user.getEmail(), subject, content); return "home";}
La clase de herramientas de correo electrónico:
public class EmailTools { private Properties props; private Key internalKey; public EmailTools(Properties props, Key internalKey){ this.props=props; this.internalKey=internalKey; } public synchronized void SendEmail(String toAddress, String subject, String content) { final String fromAddress = props.getProperty("from.address"); final String password = Encryptor.decrypt(props.getProperty("email.password"),internalKey); Session session = Session.getInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(fromAddress, password); } }); try { Message message = new MimeMessage(session); message.setFrom(new InternetAddress(fromAddress)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress)); message.setSubject(subject); message.setText(content); Transport.send(message); System.out.println("Done"); } catch (MessagingException e) { throw new RuntimeException(e); } } }En la actualidad, la clase emailTools es un singleton. ¿He puesto un bloque sincronizado alrededor del método sendEmail para que sea seguro para subprocesos?
1) ¿Es seguro el subproceso del método actual? 2) Si es así, ¿es mejor hacer que el alcance de las herramientas de correo electrónico sea un prototipo/solicitud/sesión o un singleton que use sincronización? ¿Cual es mejor?
De acuerdo con Threadsafety en Javamail , todas las operaciones relacionadas con la Session y Transport son seguras para subprocesos.
Entonces, si su Encryptor.decrypt() es seguro para subprocesos, entonces SendEmail() también es seguro para subprocesos y no se necesita sincronización.
Pero no está claro si registerUser() es seguro para subprocesos. Si RegisterUserDetails es un singleton Y setUser() es en realidad un setter que modifica algún estado compartido (y no un método que simplemente guarda algo en la base de datos), Y SendEmail() usa (indirectamente) ese estado compartido (¿usuario?) (para ejemplo, en Encryptor.decrypt() ), entonces toda la construcción puede no ser segura para subprocesos.