源码meethigher/springboot-strategy-mode
参考文章
还是来自于工作上的一点心得。之前我做的数据库的通用调用存储过程的代码,是使用抽象工厂来实现的,里面有if..else..的操作。如果要频繁的新加数据库实现逻辑,就要不断的添加实现类和else if。这边就想用注解的方式,来去除if..else..
一、简单demo
案例:发送不同类型的消息
创建注解
1 2 3 4 5 6 7
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MsgType { MessageType value(); }
|
创建类型
1 2 3 4 5 6 7 8 9 10
| public enum MessageType {
WECHAT_MSG,
SMS_MSG }
|
创建接口
1 2 3 4 5 6 7 8
| public interface MessageHandler {
String sendMessage(String msg); }
|
创建SMS实现类
1 2 3 4 5 6 7 8 9 10
| @Service @MsgType(value = MessageType.SMS_MSG) public class SmsMessageHandler implements MessageHandler { @Override public String sendMessage(String msg) { String message = "短信消息:" + msg; System.out.println(message); return message; } }
|
创建WECHAT实现类
1 2 3 4 5 6 7 8 9 10
| @Service @MsgType(value = MessageType.WECHAT_MSG) public class WechatMessageHandler implements MessageHandler { @Override public String sendMessage(String msg) { String message = "微信消息:" + msg; System.out.println(message); return message; } }
|
创建配置类
- 通过注解拿到所有被标注的bean类
- 遍历所有bean,拿到bean的类型、字节码
- 将类型、字节码存入全局map
- 使用时,通过类型,将字节码取出,instance或者通过spring放入bean容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| @Component public class MessageConfig implements ApplicationContextAware { private static Map<MessageType, Class<MessageHandler>> messageTypeClassMap = new HashMap<>();
@Autowired private ApplicationContext applicationContext;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { Map<String, Object> beans = applicationContext.getBeansWithAnnotation(MsgType.class); Iterator<String> iterator = beans.keySet().iterator(); while (iterator.hasNext()) { String beanName = iterator.next(); @SuppressWarnings("unchecked") Class<MessageHandler> messageHandlerClass = (Class<MessageHandler>) beans.get(beanName).getClass(); MessageType messageType = messageHandlerClass.getAnnotation(MsgType.class).value(); messageTypeClassMap.put(messageType, messageHandlerClass); }
}
public MessageHandler getMessageHandler(MessageType messageType) { Class<MessageHandler> messageHandlerClass = messageTypeClassMap.get(messageType); if (ObjectUtils.isEmpty(messageHandlerClass)) { throw new IllegalArgumentException("没有指定类型"); } return applicationContext.getBean(messageHandlerClass); } }
|
二、实际案例
案例:根据频次来进行工作,频次有,一天一次,三天一次,七天一次,十天一次
创建枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public enum WorkFrequency {
ONE_DAY_PER_TIMES("1天/次", "0", "oneDayPerTimes"),
THREE_DAY_PER_TIMES("3天/次", "1", "threeDayPerTimes"),
SEVEN_DAY_PER_TIMES("7天/次", "2", "sevenDayPerTimes"),
TEN_DAY_PER_TIMES("10天/次", "3", "tenDayPerTimes"), ; public final String name; public final String value; public final String uniqueCode;
WorkFrequency(String name, String value, String uniqueCode) { this.name = name; this.value = value; this.uniqueCode = uniqueCode; }
public static WorkFrequency getByUniqueCode(String uniqueCode) { for (WorkFrequency frequency : WorkFrequency.values()) { if (frequency.uniqueCode.equals(uniqueCode)) { return frequency; } } return null; } }
|
创建注解
1 2 3 4 5 6 7
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface FrequencyAnnotation { WorkFrequency value(); }
|
创建接口
1 2 3 4 5 6 7 8 9 10 11
| public interface WorkFrequencyHandler {
boolean isTodayShouldExecute(Long lastExecuteTime); }
|
创建实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| public class WorkTimeUtils {
public static int intervalDays(Date startTime, Date endTime) { Calendar cal1 = Calendar.getInstance(); cal1.setTime(startTime); Calendar cal2 = Calendar.getInstance(); cal2.setTime(endTime); int day1 = cal1.get(Calendar.DAY_OF_YEAR); int day2 = cal2.get(Calendar.DAY_OF_YEAR); int year1 = cal1.get(Calendar.YEAR); int year2 = cal2.get(Calendar.YEAR); if (year1 != year2) { int timeDistance = 0; for (int i = year1; i < year2; i++) { if ((((i % 4) == 0) && ((i % 100) != 0)) || ((i % 400) == 0)) { timeDistance += 366; } else { timeDistance += 365; } } return (timeDistance + (day2 - day1)); } else { return (day2 - day1); } } }
@Service @FrequencyAnnotation(value = WorkFrequency.ONE_DAY_PER_TIMES) public class OneDayOnceHandler implements WorkFrequencyHandler {
private final Integer INTERVAL_DAY = 1;
@Override public boolean isTodayShouldExecute(Long lastExecuteTime) { long currentTimeMillis = System.currentTimeMillis(); int realIntervalDay = WorkTimeUtils.intervalDays(lastExecuteTime, currentTimeMillis); if (realIntervalDay >= INTERVAL_DAY) { return true; } else { return false; } } }
@Service @FrequencyAnnotation(value = WorkFrequency.THREE_DAY_PER_TIMES) public class ThreeDayOnceHandler implements WorkFrequencyHandler {
private final Integer INTERVAL_DAY = 3;
@Override public boolean isTodayShouldExecute(Long lastExecuteTime) { long currentTimeMillis = System.currentTimeMillis(); int realIntervalDay = WorkTimeUtils.intervalDays(lastExecuteTime, currentTimeMillis); if (realIntervalDay >= INTERVAL_DAY) { return true; } else { return false; } } }
@Service @FrequencyAnnotation(value = WorkFrequency.SEVEN_DAY_PER_TIMES) public class SevenDayOnceHandler implements WorkFrequencyHandler {
private final Integer INTERVAL_DAY = 7;
@Override public boolean isTodayShouldExecute(Long lastExecuteTime) { long currentTimeMillis = System.currentTimeMillis(); int realIntervalDay = WorkTimeUtils.intervalDays(lastExecuteTime, currentTimeMillis); if (realIntervalDay >= INTERVAL_DAY) { return true; } else { return false; } } }
@Service @FrequencyAnnotation(value = WorkFrequency.TEN_DAY_PER_TIMES) public class TenDayOnceHandler implements WorkFrequencyHandler {
private final Integer INTERVAL_DAY = 10;
@Override public boolean isTodayShouldExecute(Long lastExecuteTime) { long currentTimeMillis = System.currentTimeMillis(); int realIntervalDay = WorkTimeUtils.intervalDays(lastExecuteTime, currentTimeMillis); if (realIntervalDay >= INTERVAL_DAY) { return true; } else { return false; } } }
|
添加配置类,通过配置类,直接获取Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| @Configuration public class WorkFrequencyConfig implements ApplicationContextAware {
private static Map<WorkFrequency, Class<WorkFrequencyHandler>> workFrequencyClassMap = new HashMap<>();
@Autowired private ApplicationContext applicationContext;
@Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { applicationContext.getBeansWithAnnotation(FrequencyAnnotation.class) .entrySet() .iterator() .forEachRemaining(stringObjectEntry -> { Class<WorkFrequencyHandler> aClass = (Class<WorkFrequencyHandler>) stringObjectEntry.getValue().getClass(); WorkFrequency messageType = aClass.getAnnotation(FrequencyAnnotation.class).value(); workFrequencyClassMap.put(messageType, aClass); }); }
public WorkFrequencyHandler getFrequencyHandler(WorkFrequency messageType) { Class<WorkFrequencyHandler> workFrequencyHandlerClass = workFrequencyClassMap.get(messageType); if (ObjectUtils.isEmpty(workFrequencyHandlerClass)) { throw new IllegalArgumentException("没有指定类型"); } return applicationContext.getBean(workFrequencyHandlerClass); } }
|
所有的配置好了,开始使用了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| @SpringBootTest public class WorkTest {
@Autowired private WorkFrequencyConfig workFrequencyConfig;
@Test public void test() { People people = new People();
WorkFrequency workFrequency = WorkFrequency.getByUniqueCode(people.getFrequency()); WorkFrequencyHandler handler = workFrequencyConfig.getFrequencyHandler(workFrequency); boolean todayShouldExecute = handler.isTodayShouldExecute(people.getLastWorkTime()); if(todayShouldExecute) { System.out.println("今天应该工作"); }else { System.out.println("今天不应该工作"); } }
static class People { private String frequency;
private Long lastWorkTime;
public People() { this.frequency = "oneDayPerTimes"; this.lastWorkTime = System.currentTimeMillis(); }
public String getFrequency() { return frequency; }
public void setFrequency(String frequency) { this.frequency = frequency; }
public Long getLastWorkTime() { return lastWorkTime; }
public void setLastWorkTime(Long lastWorkTime) { this.lastWorkTime = lastWorkTime; } } }
|