动态代理的理解
在实现动态代理我们需要编写一个代理对象和被代理对象之间的中介类
InvocationHandler 从名称可以知道中介类需要实现这个接口实现调用处理器实例
InvocationHandler 的代码如下
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
proxy:代理对象
method:声明代理接口的方法名称
args:声明接口是所传的参数
private static HttpProxyInvocation proxyHandler = new HttpProxyInvocation();
创建一个代理对象的调用处理器
Proxy:实现一个动态代理代理类的实例
这是api 上定义的一个方法名称:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
通过newProxyInstance 源码来看看他们三者的关系:
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
if (h == null) {
throw new NullPointerException();
}
/*
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, interfaces);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
return newInstance(cons, h);
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}
}
getProxyClass0(loader, interfaces) 这句代码给关联了newProxyInstance 方法的前两个参数,
我们根据以上api 的方法创建一个代理实例也是我们上面所提及到的代理类和被代理类之间的中介类–代理对象
(IHttpService) Proxy.newProxyInstance(proxyHandlerNoDialog.getClass().getClassLoader(), new Class[]{IHttpService.class}, proxyHandlerNoDialog);
实现例子:
HttpProxyInvocation
public class HttpProxyInvocation implements InvocationHandler
{
private AsyncHttpClient client = new AsyncHttpClient();
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable
{
String[] arguments = method.getAnnotation(HttpRequest.class).arguments();
Class<?> resultCls = method.getAnnotation(HttpRequest.class).resultClass();
String refreshMethod = method.getAnnotation(HttpRequest.class).refreshMethod();
String baseURL = method.getAnnotation(HttpRequest.class).baseURL();
HttpResponseHandler response = ReflectUtils.constructHttpResponse(params[0], resultCls, refreshMethod);
client.post(baseURL + method.getName(), createRequestParams(arguments, params,baseURL + method.getName()), response);
// Log.i("grage",baseURL +method.getName());
return new Object();
}
private RequestParams createRequestParams(String[] arguments, Object[] params,String url)
{
RequestParams requestParams = new RequestParams();
requestParams.put("timestamp",timestamp);
requestParams.put("msg",msg);
requestParams.put("key", Constant.key);
return requestParams;
}
}
ProxyUtils:
public class ProxyUtils {
private static HttpProxyInvocation proxyHandler = new HttpProxyInvocation();
private static HttpResponseFileUpLoadInvocation proxyHandlerUpLoadFile= new HttpResponseFileUpLoadInvocation();
public static IHttpService getHttpProxy() {
return (IHttpService) Proxy.newProxyInstance(proxyHandler.getClass().getClassLoader(), new Class[]{IHttpService.class}, proxyHandler);
}
}
ReflectUtils:
public class ReflectUtils {
private ReflectUtils() {
}
public static void invokeMethod(Object receiver, String methodName, Object param, Class<?> parameterTypes) {
try {
Method declaredMethod = getDeclaredMethod(receiver, methodName, parameterTypes);
declaredMethod.setAccessible(true);
declaredMethod.invoke(receiver, param);
} catch (Exception e) {
e.printStackTrace();
Log.e(receiver.getClass().getSimpleName(), e.getMessage());
}
}
public static void invokeMethod(Object receiver, String methodName, Object param, Object param1st, Class<?>... parameterTypes) {
try {
Method declaredMethod = getDeclaredMethod(receiver, methodName, parameterTypes);
declaredMethod.setAccessible(true);
declaredMethod.invoke(receiver, param, param1st);
} catch (Exception e) {
e.printStackTrace();
Log.e(receiver.getClass().getSimpleName(), e.getMessage());
}
}
public static void invokeMethod(Object receiver, String methodName) {
try {
Method method = getDeclaredMethod(receiver, methodName);
method.setAccessible(true);
method.invoke(receiver);
} catch (Exception e) {
Log.e(receiver.getClass().getSimpleName(), e.getMessage());
}
}
public static HttpResponseHandler constructHttpResponse(Object context, Class<?> resultCls, String refreshMethod)
throws Exception {
Constructor<HttpResponseHandler> constructor = HttpResponseHandler.class.getConstructor(Object.class, Class.class,
String.class);
return constructor.newInstance(context, resultCls, refreshMethod);
}
public static NoDialogResponseHandler constructNoDialogResponse(Object context, Class<?> resultCls, String refreshMethod)
throws Exception
{
Constructor<NoDialogResponseHandler> constructor = NoDialogResponseHandler.class.getConstructor(Object.class, Class.class,
String.class);
return constructor.newInstance(context, resultCls, refreshMethod);
}
private static Method getDeclaredMethod(Object receiver, String methodName, Class<?>... parameterTypes) {
Method method = null;
for (Class<?> clazz = receiver.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) {
try {
method = clazz.getDeclaredMethod(methodName, parameterTypes);
return method;
} catch (Exception e) {
continue;
}
}
throw new NoSuchMethodError(methodName);
}
}
HttpResponseHandler:
public class HttpResponseHandler extends JsonHttpResponseHandler
{
private static final int HTTP_SUCCESS = 1;
private static final int HTTP_SUCCESS_200 = 200;
private static final int SESSION_INVALID = -1;
private static final String OPCODE = "status";
private static final String DATA = "data";
private static final String ERROR = "showErrorMessage";
private Object context;
private Class<?> resultCls;
private String refreshMethod;
private int opcode;
public HttpResponseHandler(Object context, Class<?> resultCls, String refreshMethod)
{
this.context = context;
this.resultCls = resultCls;
this.refreshMethod = refreshMethod;
}
@Override
public void onStart()
{
DialogUtils.showLoading(context, refreshMethod);
}
@Override
public void onFinish()
{
DialogUtils.dismissLoading(refreshMethod);
}
@Override
public void onSuccess(JSONObject response)
{
try
{
Log.i("grage", response.toString());
if (response.toString().contains("userId")&&response.toString().contains("token")&&response.toString().contains("code"))
{
opcode = response.getInt("code");
}else {
opcode = response.getInt(OPCODE);
}
switch (opcode)
{
case HTTP_SUCCESS:
Object bean = JsonUtils.parserJSONObject(response.toString(), resultCls);
ReflectUtils.invokeMethod(context, refreshMethod, bean, resultCls);
break;
case HTTP_SUCCESS_200:
bean = JsonUtils.parserJSONObject(response.toString(), resultCls);
ReflectUtils.invokeMethod(context, refreshMethod, bean, resultCls);
break;
case SESSION_INVALID:
SessionUtils.clearUserId();
throw new JSONException(response.getString(DATA));
default:
throw new JSONException(response.getString(DATA));
}
} catch (Exception e)
{
ReflectUtils.invokeMethod(context, ERROR, opcode, e.getMessage(), Integer.class, String.class);
}
}
@Override
public void onFailure(Throwable e, JSONObject errorResponse)
{
// DialogUtils.dismissLoading(refreshMethod);
ToastUtils.custom("请求失败");
Log.e("grage", errorResponse.toString());
}
@Override
public void onFailure(Throwable e)
{
// DialogUtils.dismissLoading(refreshMethod);
Log.e("grage", e.toString());
}
}