动态代理实现拦截加注释的类和加注释的私有参数

动态代理是为要代理的类的方法前后加上你想要的实现,比如日志,对字符串加解密等。下面是实现对注解类的私有方法重新赋值的代码,包括请求和返回。使用的jdk1.8

public class AncryptInvoke implements InvocationHandler {

    private Object obj;

public void setobj(Object obj) {
this.obj = obj;//对象传入也可以用构造器传入,这里我就只是用了set注入
}


/**
* 控制拦截调用器

* @param o 需要被控制的对象
* @return 你传入对象的接口或者你传入的对象
*/
public static Object getProxy(Object o) {


AncryptInvoke ancryptInvoke = new AncryptInvoke();// 此处应该不可以用静态类,用的话,访问频繁的话,o对象应该会发生线程安全问题(个人理解)
ancryptInvoke.setobj(o);
return Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), ancryptInvoke);//动态生成你所需要的类,已经在类的方法里加了前后拦截


}


@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
hanglerRequestParamer(args);//方法执行前拦截,args是你方法的参数
Object result = method.invoke(obj, args);//方法执行,result是方法的返回值
if (result != null)
result = hanglerRsponseParamer(result);//对返回值进行拦截操作
return result;
}


/***
* 处理返回时拦截,这个方法只实现了list和普通对象,如果是map的话,没有实现

* @param result
* @return
*/
private Object hanglerRsponseParamer(Object result) {
if (List.class.isAssignableFrom(result.getClass())) {// isAssignableFrom是用来判断一个类Class1和另一个类Class2是否相同或者class1是否是class2的超类或接口。父类和超类在前

System.out.println("处理list的返回参数");
@SuppressWarnings("unchecked")
List list = (List) result;
for (Object object : list) {
reflectParamer(object);//处理有注解的类和参数
}
} else {


System.out.println("处理非集合的返回参数");
reflectParamer(result);
}
return result;
}


/**
* 处理请求时拦截

* @param args
*/
private void hanglerRequestParamer(Object[] args) {
if (args == null || args.length == 0)
return;
for (Object object : args) {
reflectParamer(object);
}
}


/**
* 通过反射注解处理加注解的类的注解参数

* @param object
*/
private void reflectParamer(Object object) {
// 获取类方法上的注解
Annotation[] at = object.getClass().getAnnotations();
// 无注解,不处理
if (at == null || at.length == 0)
return;
// 获取私有成员变量遍历
Field[] field = object.getClass().getDeclaredFields();
for (Field f : field) {
// 获取私有成员变量注解
Annotation[] annotatedTypes = f.getDeclaredAnnotations();
if (annotatedTypes == null || annotatedTypes.length == 0)
continue;
// 为得到私有成员变量的值,开通权限
f.setAccessible(true);
// 得到私有成员变量的值
Object o;
try {
o = f.get(object);
if (o == null)
continue;


f.set(object, new Object());// 为私有变量重新赋值


} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}

你可能感兴趣的:(Java)