处理器接口:
public interface PushProcessorInterface {
public void push(AndroidAndIosPushEvent event);
}
实现类1:
@Component
@PushProcessor(type = PushTypeEnum.all)
public class AllPushProcessor implements PushProcessorInterface {
private static final Logger logger = LoggerFactory.getLogger(AllPushProcessor.class);
public final PushTypeEnum pushType = PushTypeEnum.all;
@Autowired
private UserPushService userPushService;
@Autowired
private SendSMS sendSMS;
@Autowired
private TbOrderPushMapper orderPushMapper;
@Override
public void push(AndroidAndIosPushEvent event) {
String msg = event.getMsg();
userPushService.orderPushMsg(event.getUserId(), msg, event.getItem());
String phone = event.getPhone();
//发送短信
if (phone != null && !phone.equals("")){
//推送一条消息到用户手机
int result = sendSMS
.sendOrderMsg(phone,msg);
if (result == 0){
if (event.getRecord() != null){
int insert = orderPushMapper.insertSelective(event.getRecord());
}else{
logger.info("存储推送信息失败,您未传入推送对象!");
}
}else{
logger.info("发送手机失败!");
}
}else{
logger.info("卖家未输入手机号,无法发送短信!");
}
}
}
实现类2:
@Component
@PushProcessor(type = PushTypeEnum.app)
public class AppPushProcessor implements PushProcessorInterface {
private static final Logger logger = LoggerFactory.getLogger(AppPushProcessor.class);
public final PushTypeEnum pushType = PushTypeEnum.app;
@Autowired
private UserPushService userPushService;
@Override
public void push(AndroidAndIosPushEvent event) {
userPushService.orderPushMsg(event.getUserId(), event.getMsg(), event.getItem());
}
}
实现类3:
@Component
@PushProcessor(type = PushTypeEnum.sms)
public class SmsPushProcessor implements PushProcessorInterface {
private static final Logger logger = LoggerFactory.getLogger(SmsPushProcessor.class);
public final PushTypeEnum pushType = PushTypeEnum.sms;
@Autowired
private SendSMS sendSMS;
@Autowired
private TbOrderPushMapper orderPushMapper;
@Override
public void push(AndroidAndIosPushEvent event) {
String phone = event.getPhone();
//发送短信
if (phone != null && !phone.equals("")){
//推送一条消息到用户手机
int result = sendSMS
.sendOrderMsg(phone,event.getMsg());
if (result == 0){
if (event.getRecord() != null){
int insert = orderPushMapper.insertSelective(event.getRecord());
}else{
logger.info("存储推送信息失败,您未传入推送对象!");
}
}else{
logger.info("发送手机失败!");
}
}else{
logger.info("卖家未输入手机号,无法发送短信!");
}
}
}
标注实现类的注解:
public enum PushTypeEnum {
sms("短信", "9001"),
app("app", "1"),
all("所有", "0");
private String message;
private String code;
private PushTypeEnum(String message, String code) {
this.message = message;
this.code = code;
}
public static PushTypeEnum get(String code) {
for (PushTypeEnum ae : PushTypeEnum.values()) {
if (ae.getCode().equals(code)) {
return ae;
}
}
return null;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
工厂:spring初始化实现类到pushProcessorMap中,提供给工厂生产。
@Component
public class PushProcessorFactory implements ApplicationListener {
private Map pushProcessorMap;
@Autowired
private AllPushProcessor allPushProcessor;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
pushProcessorMap = event.getApplicationContext().getBeansWithAnnotation(PushProcessor.class);
}
/**
* 根据推送类型枚举生产推送处理器
* @param pushTypeEnum
* @return
*/
public PushProcessorInterface create(PushTypeEnum pushTypeEnum){
if (pushTypeEnum == null){
return allPushProcessor;
}
for (Object value : pushProcessorMap.values()) {
PushProcessorInterface pushProcessor = (PushProcessorInterface) value;
Annotation[] annotations = pushProcessor.getClass().getAnnotations();
for (int i = 0; i < annotations.length; i++) {
Annotation annotation = annotations[i];
if (annotation instanceof PushProcessor){
if (pushTypeEnum.equals(annotation)){
PushProcessor processor = (PushProcessor)annotation;
PushTypeEnum type = processor.type();
if (pushTypeEnum.equals(type)){
return pushProcessor;
}
}
}
}
}
return allPushProcessor;
}
}
调用方法:
PushProcessorInterface pushProcessor = factory.create(event.getPushTypeEnum());
pushProcessor.push(event);
其它附加类:
1、推送对象
/**
* 推送对象
*/
public class PushBean extends ApplicationEvent {
public PushBean
(Object source, String phone, Long userId, String msg, Object item, TbOrderPush record, PushTypeEnum pushTypeEnum) {
super(source);
this.phone = phone;
this.userId = userId;
this.msg = msg;
this.item = item;
this.record = record;
this.pushTypeEnum = pushTypeEnum;
}
/** 接受者用户手机号 */
private String phone;
/** 接收者用户id */
private Long userId;
/** 推送的消息 */
private String msg;
/** 推送附带的商品对象 */
private Object item;
/** 推送记录 */
private TbOrderPush record;
/**
* 推送类型
*/
private PushTypeEnum pushTypeEnum;
2、事件类:
public class AndroidAndIosPushEvent extends PushBean{
public AndroidAndIosPushEvent
(Object source, String phone, Long userId, String msg, Object item, TbOrderPush record, PushTypeEnum pushTypeEnum) {
super(source, phone, userId, msg, item, record, pushTypeEnum);
}
}
3、事件监听类:
@Component
public class AndroidAndIosPushListener {
private static final Logger logger = LoggerFactory.getLogger(AndroidAndIosPushListener.class);
@Autowired
private PushProcessorFactory factory;
@EventListener
@Async
public void push(AndroidAndIosPushEvent event) {
PushProcessorInterface pushProcessor = factory.create(event.getPushTypeEnum());
pushProcessor.push(event);
}
}
4、事件发布类:
@Service
public class BaseServiceImpl implements BaseService{
@Autowired
private ApplicationContext applicationContext;
/**
* 发布异步推送安卓事件
* @param phone 接受者用户手机号
* @param userId 接收者用户id
* @param msg 推送的消息
* @param item 推送附带的商品对象
* @param record 推送记录:用于存入数据库
*/
public void publishAndroidAndIosEvent
(String phone, Long userId, String msg, Object item, TbOrderPush record, PushTypeEnum pushTypeEnum) {
applicationContext.publishEvent(new AndroidAndIosPushEvent(this, phone, userId, msg, item, record, pushTypeEnum));
}
}
5、调用事件进行发布:
TbOrderPush record = createOrderPush
(order.getId(), orderItem.getBusinessId(), order.getBuyerId(), msg,
order.getStatus(), new Date(), orderChange.getId());
publishAndroidAndIosEvent(businessUser.getPhone(), businessUser.getId(), msg, orderItem.getTitle() , record, PushTypeEnum.app);
注:写到后面,你会发现我不想每次通过spring来获取类,那我可以通过抽象工厂来根据不同的工厂来完成bean的创建。
比如工厂1通过spring生产类,工厂2公告获取接口的所有实现类来生产类。