下面这篇文章是介绍SpringBoot的启动过程,从JDK的awt事件处理机制:事件 -> 发布事件 -> 监听者 -> 事件处理,然后由JDK的事件机制转向Spring框架对其支持与延伸,分析Spring框架再启动过程中事件触发机制与监听处理机制,最后又转向SpringBoot,讲解的非常好,感兴趣的blog可以学习了解一下。
下面是我在SpringBoot中,由Spring的事件机制,模拟一个场景,当感到饥饿时,通知厨师做饭。
首先是SpringBoot项目的pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>monic</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>monic</name>
<description>在这里我们模拟一个场景,当感到饥饿时,通知厨师做饭</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
定义事件:
package com.example.monic;
import org.springframework.context.ApplicationEvent;
/**
* 定义一个描述饥饿状态的事件
*/
public class HungryEvent extends ApplicationEvent {
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public HungryEvent(Object source) {
super(source);
}
}
定义Person:
package com.example.monic;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
/**
* Person类,如果属性hungry的值为0,则通知厨师做饭吃。
*/
@Slf4j
@Data
@Component
public class Person implements ApplicationEventPublisherAware {
private int hungry;
private String name;
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
public void isNeedEat() {
if(this.hungry == 0) {
log.warn("太饿了,需要吃东西");
new Thread(() -> this.applicationEventPublisher.publishEvent(new HungryEvent(this))).start();
log.info("通知完毕");
}
}
}
定义厨师类:
package com.example.monic;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 厨师类用于对饥饿事件的监听...
*/
@Slf4j
@Component
public class Chef implements ApplicationListener<HungryEvent> {
@Override
public void onApplicationEvent(HungryEvent event) {
if(event.getSource() instanceof Person) {
Person person = (Person)event.getSource();
log.info(person.getName() + "饿了,开始做饭");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("做饭完毕....开始吃吧");
}
}
}
Main方法:
package com.example.monic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class MonicApplication {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(MonicApplication.class, args);
Person person = applicationContext.getBean(Person.class);
person.setHungry(0);
person.setName("Tom");
person.isNeedEat();
}
}
执行Main方法后,我们可以看到如下结果:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
2019-07-02 14:45:55.999 INFO 7392 --- [ main] com.example.monic.MonicApplication : Starting MonicApplication on M7228-PC with PID 7392 (D:\IdeaProjects\springbootstudy\monic\target\classes started by Administrator in D:\IdeaProjects\springbootstudy\monic)
2019-07-02 14:45:56.015 INFO 7392 --- [ main] com.example.monic.MonicApplication : No active profile set, falling back to default profiles: default
2019-07-02 14:45:57.294 INFO 7392 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-07-02 14:45:57.310 INFO 7392 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-07-02 14:45:57.310 INFO 7392 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-07-02 14:45:57.403 INFO 7392 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-07-02 14:45:57.403 INFO 7392 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1217 ms
2019-07-02 14:45:57.559 INFO 7392 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-07-02 14:45:57.700 INFO 7392 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-07-02 14:45:57.700 INFO 7392 --- [ main] com.example.monic.MonicApplication : Started MonicApplication in 2.013 seconds (JVM running for 2.72)
2019-07-02 14:45:57.700 WARN 7392 --- [ main] com.example.monic.Person : 太饿了,需要吃东西
2019-07-02 14:45:57.700 INFO 7392 --- [ main] com.example.monic.Person : 通知完毕
2019-07-02 14:45:57.700 INFO 7392 --- [ Thread-7] com.example.monic.Chef : Tom饿了,开始做饭
2019-07-02 14:45:59.714 INFO 7392 --- [ Thread-7] com.example.monic.Chef : 做饭完毕....开始吃吧