前言
在
Spring
中实现一个观察者模式示例,调用 Controller 的接口可以触发观察者发送不通的邮件。
示例
1. controller
import com.idiudiu.api.service.observer.Subject;
import com.idiudiu.common.model.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RequestMapping("/api/msg")
@RestController
@Api(value = "消息接口")
public class MessageController {
@Autowired
private Subject emailSubject;
@ApiOperation(value = "发送测试邮件")
@GetMapping("/sendTestEmail")
public Result<String> sendTestEmail() {
emailSubject.notifyObservers(null);
return Result.responseSuccess(null);
}
}
2. service
2.1 接口
/**
* 主题接口
*/
public interface Subject {
/**
* 添加观察者
*/
void attach(Observer observer);
/**
* 移除观察者
*/
void detach(Observer observer);
/**
* 通知观察者, Object 可传任意参数
*/
void notifyObservers(Object object);
}
/**
* 观察者接口
*/
public interface Observer {
/**
* 行为
*/
void action(Object object);
}
2.2 实现
这里 Observer 实现了
ApplicationRunner
接口,在服务启动时把自己注册到 Subject 中。
import com.google.common.collect.Lists;
import com.idiudiu.api.service.observer.Observer;
import com.idiudiu.api.service.observer.Subject;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmailSubject implements Subject {
private static final List<Observer> OBSERVERS = Lists.newLinkedList();
@Override
public void attach(Observer observer) {
OBSERVERS.add(observer);
}
@Override
public void detach(Observer observer) {
OBSERVERS.remove(observer);
}
@Override
public void notifyObservers(Object object) {
OBSERVERS.forEach(observer -> observer.action(object));
}
}
import com.google.common.collect.Lists;
import com.idiudiu.api.service.observer.Observer;
import com.idiudiu.api.service.observer.Subject;
import com.idiudiu.common.utils.MailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DogObserver implements Observer, ApplicationRunner {
@Autowired
private Subject emailSubject;
@Override
public void action(Object object) {
String subject = "邮件测试Dog";
String content = "你好,我是Dog测试邮件!";
List<String> toReceivers = Lists.newArrayList("xxx@qq.com");
MailUtil.sendHtmlEmail(subject, content, toReceivers, null);
}
@Override
public void run(ApplicationArguments args) throws Exception {
emailSubject.attach(this);
}
}
import com.google.common.collect.Lists;
import com.idiudiu.api.service.observer.Observer;
import com.idiudiu.api.service.observer.Subject;
import com.idiudiu.common.utils.MailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CatObserver implements Observer, ApplicationRunner {
@Autowired
private Subject emailSubject;
@Override
public void action(Object object) {
String subject = "邮件测试Cat";
String content = "你好,我是Cat测试邮件!";
List<String> toReceivers = Lists.newArrayList("xxx@qq.com");
MailUtil.sendHtmlEmail(subject, content, toReceivers, null);
}
@Override
public void run(ApplicationArguments args) throws Exception {
emailSubject.attach(this);
}
}