Email Spring??

Buen dia, he visto varias implementaciones para enviar correos con Spring pero en todo caso cual es la mejor, que ventajas o desventajas hay en cada una de ellas??.
Hablando de SimpleMailMessage habla de un crear un hilo pero no acabo de entender como funciona, osea en este caso envía cada petición de envio en un hilo, estoy en lo correcto??

Aqui un ejemplo:
 

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

no hay hilos ahí

En ese código que muestras, se manda el correo en el mismo hilo de ejecución. Es decir, el código desde donde invoques este método que muestras, no continuará hasta que se haya enviado el correo.

Lo que hablan de crear un hilo es que tengas un hilo dedicado al envío de correos, leyendo los pendientes a enviar de una cola y los procesos que quieren enviar un correo únicamente deben poner un correo en esa cola para que se envíe desde ese hilo dedicado.

Por ejemplo.

Este código me serviria para enviar 1000 correos sin problemas?? Es decir, que no vaya a tener problemas con encolamientos y esto haga que me tire mi app(WEB).

Imagen de ezamudio

cuantos quieras

Así como está tu código, si lo invocas así, el correo se envía en el momento en que invocas el método, usando ese hilo de ejecución. El envío de un correo es algo tardado, en lo que se establece la conexión, se hace el saludo, se establece una conexión segura (si es que configuras TLS/SSL que es bastante recomendable) y luego se envían los datos, se espera respuesta del server y finalmente se cierra la conexión. Y además de eso, puedes tener problemas si estás enviando correos desde distintos hilos porque algunos servidores de correo no permiten dos conexiones simultáneas usando la misma cuenta, pueden bloquearte uno de los envíos o incluso bloquear la cuenta porque eso lo consideran spam.

Por eso se recomienda tener un hilo dedicado que tome los correos a enviar de una cola, y que los procesos que quieran enviar correos, solamente crean su mensaje y lo ponen en esa cola. El efecto final es que solamente se está enviando un correo a la vez, desde el hilo dedicado, por lo que no tienes broncas de conexiones simultáneas, y además no hay retraso alguno en el hilo que quiere enviar el correo (no se queda pasmado en lo que se envía el correo).

En mi blog escribí hace mucho algo de thread pools, en este caso con un threadpool de un solo hilo la haces. Lo mejor es que hagas cierto refactoring de tu aplicación, para tener un componente dedicado a enviar correos ya hechos. Algo así:

 

Eso lo invocas desde tu código simplemente así:

 

Las ventajas ya las mencioné. La desventaja es que el correo no se envía en el momento, de modo que si es absolutamente esencial que sepas si el correo se pudo enviar o no, necesitas agregar algún mecanismo adicional al Cartero: en vez de Runnable, la clase Enviador debería ser Callable y devolver un boolean si se pudo enviar o algo así; y en el método   del cartero en vez de void se devuelve un Future con el resultado del envío (simplemente true o false). Cuando no te interese saber si se envió el correo o no, pues nomás invocas el método como puse en el ejemplo, y cuando te interese saber si se envía, guardas la referencia al Future para revisar el resultado (cuando se envíe, que podría tardar un rato si es que se están enviando muchos mails y la cola está algo larga). Y otra desventaja es que si detienes la aplicación y hay mails encolados, no se van a enviar, a menos que agregues un método que detenga el hilo que lo invoca hasta que se hayan enviado todos los pendientes, algo así:

 

Con ese método en el Cartero, si tienes habilitado lo de context:annotation-config en tu applicationContext de Spring, entonces cuando detengas tu aplicación se invocará el shutdown que va a detener el thread pool y esperar hasta 10 segundos a que se terminen de enviar los correos (si después de 10 segundos no se han terminado de enviar, el método termina de todas formas y la secuencia de shutdown continuará).