This is the 18th day of my participation in Gwen Challenge

First said the why I use the event, such as create a order now but after I create success to send a text message to clients and a mail to remind, itself didn’t order to create a series of operation requires a lot of time but I still want to send a text message and email, time-consuming to invoke other services also accomplished during the comparison for less than customer satisfaction, So the way to use it can be said:

  1. ActiveMQ (Asynchronous)
  2. Using Spring event listening (synchronous + asynchronous)

Spring supports event listening

What is the ApplicationContext

It is the heart of Spring, and Context is usually interpreted as a Context, but is better understood as a container. ApplicationContext is the application’s container. Spring puts beans (objects) in a container and fetches them when needed using the GET method. This interface provides the ability to configure Spring applications. When the application is started, the implementation of this interface is read-only, but its content can be reloaded if the implementation supports it. ApplicationContext provides the following capabilities:

  • Application components for bean factory method, the ability to inherit org. Springframework. Beans. Factory. ListableBeanFactory
  • ‘s ability to load the resource files, the ability to inherit from org. Springframework. Core. IO. ResourceLoader
  • Publish event to registered listeners, the ability to inherit from ApplicationEventPublisher
  • Provides internationalized message access, inherited from MessageSource

Now that we know a little bit about ApplicationContext, let’s look at the event listeners provided by Spring. To implement event listening, Spring provides two top-level interfaces/abstract classes,ApplcationEvent: an abstract class that contains only a constructor and a timestamp of a long integer. Our custom Application Event needs to inherit from this abstract class. ApplicationListener: An interface containing only one method, onApplicationEvent, that each class that implements the interface must implement. Spring’s event listener is based on the standard observer pattern. If a bean implementing ApplicationListener is deployed in the ApplicationContext, So when an ApplicationEvent is published to the ApplicationContext, the bean gets notified and does something specific. From the above passage, we can easily get two reflections:

  • How is a bean that implements ApplicationListener deployed to ApplicationContext
  • How is an ApplicationEvent published to ApplicationContext

Therefore, a complete event is composed of event source, event release and event monitoring

Code sample

The statement event

public class SendEmailEvent extends ApplicationEvent {
    private String message;

    public SendEmailEvent(Object source, String message) {
        super(source);
        this.message = message;
    }

    public String sendEmail(a){
        returnmessage; }}Copy the code

Event publishing

@Component
@Slf4j
public class SendEmailEventPublisher {
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    public void publish(final String message) {
        log.info("publis a SendEmailEvent,message:{}", message + " time: " + LocalTime.now());
        SendEmailEvent sendEmailEvent = new SendEmailEvent(this, message); applicationEventPublisher.publishEvent(sendEmailEvent); }}Copy the code

Event listeners

Event listening mode 1
@Component
@Slf4j
public class SendEmailListener implements ApplicationListener<SendEmailEvent> {
    @Override
    public void onApplicationEvent(SendEmailEvent sendEmailEvent) {
        String s = sendEmailEvent.sendEmail();
        log.info("SendRegisterEmailListener message: " + s+" time: "+ LocalTime.now()); }}Copy the code
Event monitoring implementation method two
@Component
@Slf4j
public class SendEmailListener2 {
    @EventListener
    public void sendEmmail(SendEmailEvent sendEmailEvent){
        String s = sendEmailEvent.sendEmail();
        log.info("SendRegisterEmailListener message: " + s+" time: "+ LocalTime.now()); }}Copy the code

test

@RunWith(SpringRunner.class)
@SpringBootTest
public class SendEmailEventPublisherTest {
    @Resource
    private SendEmailEventPublisher sendEmailEventPublisher;

    @Test
    public void publish(a) {
        sendEmailEventPublisher.publish("La la la la"); }}Copy the code

Spring events are synchronous by default, enabling asynchrony by adding @enableAsync to the launcher class Application. Using the method annotation @async can be applied to the listener’s execution method, which executes asynchronously. @async with no arguments defaults to using the default thread pool of SpringBoot. Custom thread pools are recommended:

@Configuration
public class ThreadPoolConfig {

    @Bean("executor")
    public Executor getExecutor(a) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(10.20.60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue(10000));
        returnexecutor; }}Copy the code

conclusion

  • Through the event mechanism, the code can be decoupled, so that their own code, very clean, more extensible;
  • Asynchronous time processing mechanism can improve the response speed of the program, and the internal thread pool will greatly improve the concurrency efficiency of the program
  • Conditional and generic listeners allow you to eliminate a lot of explicit logic, making per-time listening more atomic