I have two spring beans. A JmsHandler
which receives a Message
. This is processed and handed over to a MailHandler
which sends a mail. Now I've seen that sometimes messages arrive at the JmsHandler
in exact the same time. When entering the sendMail
method one of the both isn't processed properly (no mail is sent). So I would expect that's an threading issue.
I've got two possiblities to handle this issue:
a) I set the sendMail
method as synchronized. Which means the next execution will be stopped until the first is processed.
public class JmsHandler {
@Autowired
private MailHandler mailer;
public void handleMessage(Message msg) {
mailer.sendMail(msg.getPayload().toString());
}
}
@Component
public class MailHandlerImpl implements MailHandler {
@Override
public synchronized void sendMail(String message) {
// do some fancy stuff...
// do something to mail the message.
}
}
b) I define the MailHandler to the scope "prototype" and get it using an lookup from the ApplicationContext.
public class JmsHandler {
@Autowired
private ApplicationContext ctx;
public void handleMessage(Message msg) {
MailHandler mailer = ctx.getBean(MailHandler.class)
mailer.sendMail(msg.getPayload().toString());
}
}
@Component
@Scope("prototype")
public class MailHandlerImpl implements MailHandler {
@Override
public void sendMail(String message) {
// do some fancy stuff...
// do something to mail the message.
}
}
I think both ways are ok. But in terms of performance is there any issue? When using synchronized it will stop execution of the next process and wait until the first is finished. The second will create a new Instance of MailHandlerImpl
when a message has to be send (and of course autowire other things not shown here).
Or is there a third alternative?