4

Here is my email service

@Service("mailService")
public class EmailService 
{

@Autowired
private MailSender mailSender;

@Async
public void sendMail(String to, String subject, String body) {
    SimpleMailMessage message = new SimpleMailMessage();
    message.setTo(to);
    message.setSubject(subject);
    message.setText(body);
    mailSender.send(message);

}

@Async
public void sendPreConfiguredMail(String to,SimpleMailMessage configuredMessage) {
    SimpleMailMessage mailMessage = new SimpleMailMessage(configuredMessage);
    mailMessage.setTo(to);
    mailSender.send(mailMessage);
}

}

And I use JavaMailSenderImpl to implement MailSender

 <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.gmail.com"/>
    <property name="port" value="25"/>
    <property name="username" value="xxx"/>
    <property name="password" value="xxx"/>
    <property name="javaMailProperties">
        <props>
            <prop key="mail.transport.protocol">smtp</prop>
            <prop key="mail.smtp.auth">true</prop>
            <prop key="mail.smtp.starttls.enable">true</prop>
            <prop key="mail.debug">true</prop>
        </props>
    </property>
</bean>

to let spring recognize the @Async

<mvc:annotation-driven />

<bean id="executorService" class="java.util.concurrent.Executors"
    factory-method="newFixedThreadPool">
    <constructor-arg value="10" />
</bean>

<task:executor id="threadPoolTaskExecutor" pool-size="10" />

<task:annotation-driven executor="executorService" />

<context:component-scan base-package="com.bistyle.lifelog" />

But it is said, @Async don't work in service method, right?

What should I do to implement it?

kakabali
  • 3,824
  • 2
  • 29
  • 58
karl li
  • 469
  • 1
  • 5
  • 17
  • 3
    What make you thing that "But it is said, `@Async` don't work in service method, right?" -- it should work. (If you do not use real AspectJ, then you need to invoke the `@Async`annotated method from an other bean, but this is a different topic) – Ralph Jul 22 '13 at 11:22
  • 1
    Is there any problem in my configure? In my test, browser will wait until the email is sended. And someone else tell me, it is because @Async don't work in service method. What's your opinion? – karl li Jul 22 '13 at 11:27
  • I used `@Asyn` in Service methods, and it works. -- "Is there any problem in my configure?" maybe: do you have a second spring configuration file? – Ralph Jul 22 '13 at 20:09
  • Yes , actually I hava 4 xml files for different config(like spring security). And I use contextConfigLocation to load them. – karl li Jul 23 '13 at 03:24
  • Could you please post the one (except them for security), that are loaded by the SpringContextLoader – Ralph Jul 23 '13 at 05:39
  • I have the same problem. No errors, no exception, but the mail doesn't arrive. If I remove \@Async, it works. I tried also using the executor directly with a runnable, same problem. I also tried extending JavaMailSenderImpl and using \@Async there, same result. I'm using spring 3.2.3 with JavaMail (mail not mail-api) 1.4.7 – alex Jul 29 '13 at 22:59
  • Looking at smtp logs, using async the connection ends after the login (successful) – alex Jul 29 '13 at 23:56
  • Ok, I'm dumb: it doesn't work from tests but works in the application – alex Jul 30 '13 at 01:25
  • AFAIR @Async won't show exceptions. I'm not 100% sure about that, but try to debug the failing code and you might find a helpful exception. BTW. a common pitfall is that Async is no more in a request context… but I don't see any hint for this in your case. – Markus Malkusch Jun 09 '14 at 21:38

2 Answers2

0

Try replacing:

<bean id="executorService" class="java.util.concurrent.Executors"
factory-method="newFixedThreadPool">
<constructor-arg value="10" />
</bean>

<task:executor id="threadPoolTaskExecutor" pool-size="10" />

<task:annotation-driven executor="executorService" />

WITH

<task:executor id="executorService" pool-size="10" />

<task:annotation-driven executor="executorService" />

It worked for me pretty well

lakreqta
  • 49
  • 4
0

@Async works on all @Components. I also faced the problem as like you. The client was still waiting until end of email sending process (not run with asynchronous). Due to this post ,

... that I was calling the method from within the same class. I believe this is related to Spring’s proxying mechanism.

Now I separated @Async methods from the same @Service class. That fits my problem.

Cataclysm
  • 7,592
  • 21
  • 74
  • 123