阻止事件冒泡的兩種方式
阿新 • • 發佈:2020-12-01
前言
部落格正在整理中
使用場景
靜態代理
介面
public interface IInfoService { void setInfo(); }
操作
public class InfoDao implements IInfoService { @Override public void setInfo() { Log.e("除錯_臨時_log", "設定資料中"); } }
代理
public class InfoDaoProxy implements IInfoService { private IInfoService iInfoService;public InfoDaoProxy(IInfoService service){ this.iInfoService = service; } @Override public void setInfo() { Log.e("除錯_臨時_log", "this_馬上設定"); iInfoService.setInfo(); Log.e("除錯_臨時_log", "this_設定完成"); } }
結果:
動態代理
動態代理有以下特點:
1.代理物件,不需要實現介面
2.代理物件的生成,是利用JDK的API,動態的在記憶體中構建代理物件(需要我們指定建立代理物件/目標物件實現的介面的型別)
3.動態代理也叫做:JDK代理,介面代理
JDK中生成代理物件的API
代理類所在包:java.lang.reflect.Proxy
JDK實現代理只需要使用newProxyInstance方法,但是該方法需要接收三個引數,完整的寫法是:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
注意該方法是在Proxy類中是靜態方法,且接收的三個引數依次為:
ClassLoader loader,
:指定當前目標物件使用類載入器,獲取載入器的方法是固定的Class<?>[] interfaces,
InvocationHandler h
:事件處理,執行目標物件的方法時,會觸發事件處理器的方法,會把當前執行目標物件的方法作為引數傳入
註解
@Documented @Target(METHOD) @Retention(RUNTIME) @interface Info { String name() default ""; int id() default 0; }
介面
public interface IInfoService { @Info(name = "小明", id = 1) Call setInfo(Boolean sex); }
返回操作類
public class Call { private List<Object> valueList; protected Call(List<Object> list) { valueList = list; } public String execute(){ if (valueList == null || valueList.size() == 0){ return null; } StringBuilder stringBuilder = new StringBuilder(); for (Object o : valueList){ if (o instanceof String){ stringBuilder.append(o); }else if (o instanceof Integer){ stringBuilder.append(o); }else if (o instanceof Long){ stringBuilder.append(o); }else if (o instanceof Boolean){ stringBuilder.append(o); }else if (o instanceof Float){ stringBuilder.append(o); }else if (o instanceof Double){ stringBuilder.append(o); } } return stringBuilder.toString(); } }
代理
public class InfoDaoProxy { public static <T> T create(Class<T> service){ return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } List<Object> objects = new ArrayList<>(); Info info = method.getAnnotation(Info.class); objects.add(info.name()); objects.add(info.id()); if (args != null){ for (Object o : args){ objects.add(o); } } return new Call(objects); } }); } }
End