Skip to content

Instantly share code, notes, and snippets.

@mdeverdelhan
Last active June 21, 2019 19:31
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mdeverdelhan/3990188 to your computer and use it in GitHub Desktop.
Save mdeverdelhan/3990188 to your computer and use it in GitHub Desktop.
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>
@vitorvezani
Copy link

How does this affects performance?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment