类对象操作时候在外面加一层代理,加一层壳,比如写日记功能,写在外面不接触具体操作对象,相当于代理对厂家的宣传作用。

下面是JDK动态代理
//makeProxy.javapackage daili;
import com.sun.org.apache.xpath.internal.SourceTree;
import java.lang.reflect.*;
import java.util.Arrays;
/*
这个类生成代理对象
JDK动态代理
1:Proxy:是所有动态代理的父类,专门用于生成代理类或者生成代理对象
这里的proxy是 java.lang.reflect
Class<?>(返回值) getPRoxyClass()方法用于生成对象的Class对象,就是电脑计算机中的class对象,属性就是class
object(返回值) newProxyInstance()方法用于生成代理对象的实例
2:InvocationHandler:完成动态代理的整个过程,这是一个接口,自己写一个类实现它
里面有一个invoke方法(返回值是object)
*/
public class makeProxy {
//动态代理 : 目标对象 如何获取代理对象 代理要干什么
//目标对象
private caculate cal ;
//获取代理对象需要执行方法,此时需要new makeProxy,所以直接放到构造方法中,此时的参数就是目标对象
public makeProxy(caculate cal){
this.cal = cal;
}
//获取代理对象的方法
public Object getProxy(){
//代理对象
Object proxy;
/*
第一个参数:ClassLoader对象。类加载器对象
第二个参数:interfaces :接口们。提供目标对象的所有接口,用于实现代理对象和目标对象实现的是同一个接口。就是在代理对象.之后可以出现目标对象的方法.
第三个参数:是一个实现InvocationHandler接口的类对象,这里的
*/
ClassLoader loader = cal.getClass().getClassLoader(); //类加载器
Class [] interfaces = cal.getClass().getInterfaces();
//下面这个有三个参数
proxy = Proxy.newProxyInstance(loader,interfaces,new MyInvocationHandler());
return proxy;
}
class MyInvocationHandler implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
/*
这里的proxy参数和上面的proxy = Proxy.newProxyInstance(loader,interfaces,new MyInvocationHandler());,这句话生成的proxy是一个东西,一般不要动,慎用。
这里的method是一个正在被调用的方法的对象,就是这个参数是一个对象,该对象能执行的方法就是此时正在被执行的方法,比如add方法
args是此时正在被调用方法的参数
*/
//先将正事办了,代理代理的那个目标对象的方法,先把这个执行了
System.out.println("日记执行开始:"+method.getName()+" "+ Arrays.asList(args));
Object object = method.invoke(cal,args);//执行caculateImpl里面的+ - * /
System.out.println("日记执行结束:结果是-->"+object);
return object;
}
}
}
tast.javapackage daili;
public class test {
public static void main(String[] args) {
caculate cal = new caculateImpl();
Object obj = new makeProxy(cal).getProxy();
caculate pro = (caculate) obj;
System.out.println(pro.add(1, 2));
}
/*
问题1:代理对象目标对象能否互相转化? 不行,两个只有实现的接口一样
问题2:代理对象执行代理方法,为什么会执行实现InvacationHandler对象中的invoke方法
System.out.println(pro.getClass().getName());
此时可以得到该代理对象的类名字是$Proxy0
此时底层的$Proxy0是这样实现的
class $Proxy0 extends Proxy implements caculate{
//这里的构造方法是将自己定义的MyInvocationHandler对象赋值到父类中的h
public $Proxy0(InvocationHandler h) {
super(h);
}
//在上面对父类的InvocationHandler h中的h赋值之后,每一次调用代理类的代理方法时候,都会执行下面这样的invoke方法。
@Override
public int add(int a, int b) {
return super.h.invoke(this,对象方法,对象参数); 执行父类中的invoke方法,也就是那个自己写的invoke方法。
}
}
*/
}
//caculateImpl.java
package daili;
public class caculateImpl implements caculate {
@Override
public int add(int a, int b) {
return a+b;
}
}
//caculate.javapackage daili;
public interface caculate {
public int add(int a,int b);
}
代理模式有两种,基于接口的,基于继承的
基于接口的:代理类和普通类只能代理接口里面的方法,目标对象中声明的新方法,代理对象代理不了
基于继承的:代理继承目标对象,这样在目标对象中自己写的方法也可以代理。
来源:https://www.cnblogs.com/0123wtdd/p/12293007.html