代理(Proxy)
调用objProxy.add("abc");方法时,设计三个要素,当前的代理对象,调用的那个方法,参数列表
invoke(Objectobj,Method method,Object[] obj);三个要素和参数对应
理解动态代理类中的方法
例如objProxy.size();
则在代理类中有个size(){
调用InvocationHanler对象中的invoke(,,);可以再invoke()方法中调用目标对象的方法进行执行
返回值要和size的方法一致
}
程序:
publicclass ProxyTest {
/**
* @param args
* @throws Exception
* @throws
*/
publicstatic void main(String[] args) throws Exception {
//得到动态代理对象的字节码对象
ClassclazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);//哪个类加载器,对应类实现的接口。目标对象和代理对象实现同一个接口。该接口的类加载器。
//获取对应类的构造方法
System.out.println("----------beginconstructors list--");
Constructor[]constructors = clazzProxy1.getConstructors();
for(Constructorcon : constructors){
StringBuildersBuilder = new StringBuilder();
sBuilder.append('(');
Class[]parameterName = con.getParameterTypes();//得到参数类型
for(Classc : parameterName){
sBuilder.append(c.getName()+",");
}
if(parameterName!=null&& parameterName.length!=0){
sBuilder.deleteCharAt(sBuilder.length()-1);
}
sBuilder.append(')');
System.out.print(con.getName());
System.out.println(sBuilder.toString());
}
System.out.println("----------beginMethods list--");
Method[]methods = clazzProxy1.getMethods();
for(Methodcon : methods){
StringBuildersBuilder = new StringBuilder();
sBuilder.append('(');
Class[]parameterName = con.getParameterTypes();//得到参数类型
for(Classc : parameterName){
sBuilder.append(c.getName()+",");
}
if(parameterName!=null&& parameterName.length!=0){
sBuilder.deleteCharAt(sBuilder.length()-1);
}
sBuilder.append(')');
System.out.print(con.getName());
System.out.println(sBuilder.toString());
}
//第一种获得动态代理对象
Constructorconstructor = clazzProxy1.getConstructor(InvocationHandler.class);
CollectionPxoxy1 = (Collection)constructor.newInstance(new MyInvocationHandler());
//第二种获得动态代理对象,使用匿名内部类
CollectionPxoxy2 = (Collection)constructor.newInstance(new InvocationHandler(){
@Override
publicObject invoke(Object proxy, Method method, Object[] args)
throwsThrowable {
//TODO Auto-generated method stub
returnnull;
}
});
//第三种
Collectionproxy3 = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
newClass[]{Collection.class},new InvocationHandler(){
ArrayListtarget = new ArrayList();
@Override
publicObject invoke(Object proxy, Method method,
Object[]args) throws Throwable {
longbegintime = System.currentTimeMillis();
ObjectretVal = method.invoke(target, args);
longendtime = System.currentTimeMillis();
System.out.println(method.getName()+"timeof "+(endtime-begintime));
//TODO Auto-generated method stub
returnretVal;
}
});
proxy3.add("xky");
proxy3.add("kkk");
System.out.println(proxy3.size());
}
}
//创建代理对象
classMyInvocationHandler implements InvocationHandler{
@Override
publicObject invoke(Object proxy, Method method, Object[] args)
throwsThrowable {
//TODO Auto-generated method stub
returnnull;
}
}
上面的程序目标对象是硬编码
改动的代码
ArrayList target = new ArrayList(); //确定代理的对象目标
//参数一个是目标对象,一个是一个契约,也就是实现一个接口的对象。
Collectionproxy4 = (Collection)getProxy(target,new MyAdvice());
privatestatic Object getProxy(final Object target,final Advice advice) {
Objectproxy3 = (Collection)Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),newInvocationHandler(){
@Override
publicObject invoke(Object proxy, Method method,
Object[]args) throws Throwable {
advice.getBeginTime(method);
ObjectretVal = method.invoke(target, args);
advice.getEndTime(method);
returnretVal;
}
});
returnproxy3;
}
实现某个接口的类(定义操作目标对象前后的操作,或者异常,或者前,或者后),只要在InvocationHandler中引用即可
publicclass MyAdvice implements Advice {
longbegintime = 0;
@Override
publicvoid getBeginTime(Method method){
//TODO Auto-generated method stub
System.out.println("马上去传智播客");
begintime = System.currentTimeMillis();
}
@Override
publicvoid getEndTime(Method method) {
//TODO Auto-generated method stub
System.out.println("传智播客毕业");
longendtime = System.currentTimeMillis();
System.out.println(method.getName()+"timeof "+(endtime-begintime));
}
}