最近有業務需求,在寫消息推方面(APP,SMS)的實現代碼,因爲一些特殊緣由(網絡),須要實現一個消息重發的機制(若是發送失敗的話,則從新發送,最多發送N次) java
因爲以上的一個需求,在實現的過程當中,最開始想到的是使用監聽(相似觀察者模式的感受),發送失敗的話,即有相應的處理邏輯,可是因爲一些緣由,並無使用這個方法,使用瞭如下書寫的代理和註解機制,實現了重發效果,具體消息發送的代碼使用dosomething代替; 網絡
若是您還有其餘更好的方法,歡迎指導。 app
如下貼出來個人一些實現代碼: ide
package test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 默認的重試次數 * @author alexgaoyh * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SMSRetry { int times() default 1; }
package test; /** * 發送接口 * @author alexgaoyh * */ public interface SMSToSend { @SMSRetry(times = 5) void doSomething(String thing); }
package test; /** * 發送服務 * @author alexgaoyh * */ public class SMSService implements SMSToSend { @Override public void doSomething(String thing) { System.out.println(thing); //若是下面的代碼行並無被註釋,說明在發送過程當中拋出了異常,那麼接下來,會持續發送SMSToSend接口中定義的5次消息 //throw new RuntimeException(); } }
package test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 代理模式 * @author alexgaoyh * */ public class SMSRetryProxy implements InvocationHandler { private Object object; @SuppressWarnings("unchecked") public <T> T getInstance(T t) { object = t; return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t .getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { int times = method.getAnnotation(SMSRetry.class).times(); Object result = null; while (times-- > 0) { try { result = method.invoke(object, args); break; } catch (Exception e) { System.out.println(e.getStackTrace()); System.out.println("error happend, retry"); } } return result; } }
package test; /** * 短信業務爲SMS "short message service" * 客戶端測試方法 * @author alexgaoyh * */ public class SMSClient { public static void main(String[] args) { SMSToSend toDo = new SMSRetryProxy().getInstance(new SMSService()); toDo.doSomething("== (short message service)send short messages =="); } }
以上代碼很簡單,不過多進行解釋; 測試
重發次數定義在‘發送接口中’5次,具體的發送代碼在‘SMSService’中 this