Descripción del observador
1. El concepto básico del modo observador
Cuando el estado de un objeto cambia, se notifica a todos los demás objetos.
2. Escenarios de aplicación del modo observador
Monitoreo de eventos Zk, centro de configuración distribuido, actualización de archivos de configuración y envío masivo de mensajes desde diferentes canales de la empresa.
1. Utilice el modo de observador para configurar el monitoreo
El uso del modo de observador es una ejecución asincrónica de notificaciones de mensajes multicanal (SMS + buzón de correo + envío de mensajes de cuenta oficial, etc.)
1. Clase de herramienta SpringUtils
/**
* SpringUtils 工具类
*/
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static <T> T getBean(String beanId) {
return (T) applicationContext.getBean(beanId);
}
public static <T> T getBean(Class<T> requiredType) {
return (T) applicationContext.getBean(requiredType);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
}
2. Cree una interfaz de observador
/**
* 观察者接口
*/
public interface ObServer {
void sendMsg(JSONObject jsonObject);
}
3. Crea Observer One
@Component
@Slf4j
public class EmailObServer implements ObServer {
@Override
public void sendMsg(JSONObject jsonObject) {
log.info("使用观察者发送邮件");
}
}
4. Cree el observador dos
@ Slf4j
@Component
public class SMSObServer implementa ObServer { @Override public void sendMsg (JSONObject jsonObject) {log.info ("Usar observador para enviar SMS"); } }
5. Todos, contenedor de observadores
import com.alibaba.fastjson.JSONObject;
import com.xijia.xj.observer.ObServer;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 观察者容器, listObServer = 所有的观察类
* @author wangsong
* @mail [email protected]
* @date 2020/9/2 0002 21:22
* @version 1.0.0
*/
@Component
public class XjSubject {
/**
* 类型 ObServer
*/
private List<ObServer> listObServer = new ArrayList<>();
/**
* 线程池
*/
private ExecutorService executorService;
public XjSubject() {
executorService = Executors.newFixedThreadPool(10);
}
/**
* 新增ObServer
*
* @param obServer
*/
public void addObServer(ObServer obServer) {
listObServer.add(obServer);
}
/**
* 通知给所有的观察者,遍历执行所有观察者的方法
*
* @param jsonObject
*/
public void notifyObServer(JSONObject jsonObject) {
for (ObServer obServer : listObServer) {
// 单独开启线程异步通知
executorService.execute(new Runnable() {
@Override
public void run() {
obServer.sendMsg(jsonObject);
}
});
}
}
}
6. Registra automáticamente a todos los observadores en el contenedor de observadores.
import com.xijia.xj.config.SpringUtils;
import com.xijia.xj.observer.ObServer;
import com.xijia.xj.observer.subject.XjSubject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 项目启动后需要 执行的一些方法 --> 注册观察者, 当我们的SpringBoot启动成功的时候,注册我们的SMSObServer
* @author wangsong
* @mail [email protected]
* @date 2020/9/2 0002 21:27
* @version 1.0.0
*/
@Component
public class InitService implements ApplicationRunner {
@Autowired
private XjSubject xjSubject;
@Override
public void run(ApplicationArguments args) throws Exception {
/**
* 自动注册我们观察者
* 1.使用Spring获取该ObServer下有那些bean对象
* 2.直接注添加到集合中
*/
//根据接口类型返回相应的所有bean
Map<String, ObServer> map = SpringUtils.getApplicationContext().getBeansOfType(ObServer.class);
for (String key : map.keySet()) {
ObServer obServer = map.get(key);
xjSubject.addObServer(obServer);
}
}
}
7. Usa el modo de observador
@RestController
@Slf4j
public class OrderService {
@Autowired
private XjSubject xjSubject;
@RequestMapping("/addOrder")
public String addOrder() {
log.info("1.调用数据库下单订单代码:");
JSONObject jsonObject = new JSONObject();
jsonObject.put("sms", "1865891111");
jsonObject.put("email", "[email protected]");
xjSubject.notifyObServer(jsonObject);
return "success";
}
}
8. Efecto de ejecución
En segundo lugar, use Spring's Listener para monitorear
Tenga en cuenta que Spring's Listener se ejecuta de forma sincrónica y no admite la anotación asincrónica @Async
1. Cree una clase de parámetro para supervisar la entrega
package com.xijia.spring.entity;
import org.springframework.context.ApplicationEvent;
public class UserMessageEntity extends ApplicationEvent {
private String email;
private String phone;
private String userId;
/**
* Create a new ApplicationEvent.
*
* @param source the object on which the event initially occurred (never {@code null})
*/
public UserMessageEntity(Object source) {
super(source);
}
public UserMessageEntity(Object source, String email, String phone) {
super(source);
this.email = email;
this.phone = phone;
}
@Override
public String toString() {
return "email:" + email + ",phone:" + phone;
}
}
2. Cree el monitor 1 (observador 1)
/**
* 监听发送邮件
*/
@Component
public class EmailListener implements ApplicationListener<UserMessageEntity> {
/**
* 监听的方法
*
* @param event
*/
@Override
@Async
public void onApplicationEvent(UserMessageEntity event) {
System.out.println(Thread.currentThread().getName() +" 邮件:" + event.toString());
}
}
3. Cree el monitor 2 (observador 2)
/**
* 监听发送邮件
*/
@Component
public class SmSListener implements ApplicationListener<UserMessageEntity> {
/**
* 监听的方法
*
* @param event
*/
@Override
@Async
public void onApplicationEvent(UserMessageEntity event) {
System.out.println(Thread.currentThread().getName() + " 短信:" + event.toString());
}
}
4. Use Listener para monitorear
@RestController
@Slf4j
public class OrderService {
@RequestMapping("/addOrder2")
public String addOrder2() {
log.info("1.调用数据库下单订单代码:");
UserMessageEntity userMessageEntity = new UserMessageEntity(this, "[email protected]", "1865891111");
applicationEventPublisher.publishEvent(userMessageEntity);
return "success";
}
}
5. Efecto de ejecución
-
Parte del contenido anterior proviene de Ant Classroom http://www.mayikt.com/
-
Proyecto personal de código abierto (sistema de gestión de fondo universal) -> https://gitee.com/wslxm/spring-boot-plus2 , puede consultarlo si lo desea
-
Este es el final de este artículo. Si lo encuentra útil, por favor, haga clic en Me gusta o preste atención. Continuaremos actualizando más contenido de vez en cuando ... ¡Gracias por mirar!