Exception interception (AOP) and asynchronous mail sending with Spring
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:task="http://www.springframework.org/schema/task" | |
xsi:schemaLocation=" | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | |
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> | |
<!-- ... --> | |
<!-- This bean can be activated for AOP based runtime exception interceptor. | |
'exceptionInterceptor' will be called on each method of '*Controller' classes. --> | |
<bean name="exceptionInterceptor" class="com.mygroup.myapp.common.interceptor.ExceptionInterceptor"/> | |
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> | |
<property name="beanNames"> | |
<value>*Controller</value> | |
</property> | |
<property name="interceptorNames"> | |
<list> | |
<value>exceptionInterceptor</value> | |
</list> | |
</property> | |
</bean> | |
<!-- E-mails will be sent with Gmail --> | |
<bean id="mailSender" class="com.mygroup.myapp.common.task.AsyncMailSender"> | |
<property name="host" value="smtp.gmail.com" /> | |
<property name="port" value="465" /> | |
<property name="protocol" value="smtps" /> | |
<property name="username" value="myerrorsender@gmail.com" /> | |
<property name="password" value="errorSenderPassword" /> | |
<property name="javaMailProperties"> | |
<props> | |
<prop key="mail.smtps.auth">true</prop> | |
</props> | |
</property> | |
</bean> | |
<!-- Mail sending must be queued. Here is the task executor --> | |
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> | |
<property name="corePoolSize" value="5" /> | |
<property name="maxPoolSize" value="25" /> | |
<property name="queueCapacity" value="100" /> | |
</bean> | |
<task:annotation-driven executor="taskExecutor" /> | |
<!-- ... --> | |
</beans> |
package com.mygroup.myapp.common.task; | |
import org.springframework.mail.MailException; | |
import org.springframework.mail.SimpleMailMessage; | |
import org.springframework.mail.javamail.JavaMailSenderImpl; | |
import org.springframework.scheduling.annotation.Async; | |
/** | |
* Asynchronous mail sender | |
*/ | |
public class AsyncMailSender extends JavaMailSenderImpl { | |
@Async | |
public void send(SimpleMailMessage simpleMessage) throws MailException { | |
super.send(simpleMessage); | |
} | |
@Async | |
public void send(SimpleMailMessage[] simpleMessages) throws MailException { | |
super.send(simpleMessages); | |
} | |
} |
package com.mygroup.myapp.common.interceptor; | |
import java.io.PrintWriter; | |
import java.io.StringWriter; | |
import org.aopalliance.intercept.MethodInterceptor; | |
import org.aopalliance.intercept.MethodInvocation; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.mail.MailException; | |
import org.springframework.mail.MailSender; | |
import org.springframework.mail.SimpleMailMessage; | |
/** | |
* Exception interceptor (AOP) | |
*/ | |
public class ExceptionInterceptor implements MethodInterceptor { | |
private static final Logger logger = LoggerFactory.getLogger(ExceptionInterceptor.class); | |
@Autowired | |
MailSender mailSender; | |
public Object invoke(MethodInvocation method) throws Throwable { | |
Object result = null; | |
try { | |
result = method.proceed(); | |
} catch (Exception e) { | |
// Building stack trace string | |
StringWriter stackTrace = new StringWriter(); | |
e.printStackTrace(new PrintWriter(stackTrace)); | |
// Building e-mail | |
SimpleMailMessage email = new SimpleMailMessage(); | |
email.setTo("developer@myapp.tld"); | |
email.setSubject("[MyApp] Exception in '" + method.getMethod().getName() + "' method"); | |
email.setText( | |
"Exception in: " + method.getMethod().getName() + "\n\n" + | |
"Class: " + method.getMethod().getDeclaringClass().getName() + "\n\n" + | |
"Message: " + e.getMessage() + "\n\n" + | |
"StackTrace:\n" + stackTrace.getBuffer().toString() | |
); | |
// Sending e-mail | |
try { | |
this.mailSender.send(email); | |
} catch (MailException mailException) { | |
logger.error(mailException.getMessage()); | |
} | |
throw e; | |
} | |
return result; | |
} | |
} |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
<modelVersion>4.0.0</modelVersion> | |
<groupId>com.mygroup</groupId> | |
<artifactId>myapp</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
<packaging>war</packaging> | |
<name>My App</name> | |
<properties> | |
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
<java-mail.version>1.4.5</java-mail.version> | |
<spring.version>3.0.7.RELEASE</spring.version> | |
<aspectj.version>1.6.12</aspectj.version> | |
</properties> | |
<dependencies> | |
<!-- Java Mail API --> | |
<dependency> | |
<groupId>javax.mail</groupId> | |
<artifactId>mail</artifactId> | |
<version>${java-mail.version}</version> | |
</dependency> | |
<!-- Spring dependencies --> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-core</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<!-- And other Spring dependencies... --> | |
<!-- AOP --> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-aop</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-aspects</artifactId> | |
<version>${spring.version}</version> | |
</dependency> | |
<dependency> | |
<groupId>org.aspectj</groupId> | |
<artifactId>aspectjrt</artifactId> | |
<version>${aspectj.version}</version> | |
</dependency> | |
</dependencies> | |
</project> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
How does this affects performance?