前言
博客正在整理中
使用场景
静态代理
接口
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