1.创建接口
public interface iTestDemo {
void test1();
void test2();
}
2.创建类接入接口并对方法进行重写
public class iTestDemoImpl implements iTestDemo {
@Override
public void test1() {
System.out.println("执行test1方法");
}
@Override
public void test2() {
System.out.println("执行test2方法");
}
}
3.创建Test类接入接口,根据多态性用接口接收重写过的类的对象,并对需求进行实现。
public class test3 {//这是代理对象
public static void main(String[] args) {
iTestDemo test = new iTestDemoImpl();//用接口接收对象
test.test1();
test.test2();
/** 需求:
* 在执行方法时,需要加入一些东西
* 在执行方法前打印test1或test2开始执行
* 在执行方法后打印test1和test2执行完毕
* 打印的方法名要和调用的方法保持一致
*/
4.创建动态代理类ProxyDemo 并接入接口InvocationHandler,设置一个被代理对象参数Object类的obj,通过构造方法把obj对象引入
public class ProxyDemo implements InvocationHandler{
Object obj;//被代理的对象
public ProxyDemo(Object obj){ //通过构造方法把对象引入
this.obj = obj;
}
5.对InvocationHandler接口方法重写,通过method.invoke引入代理对象的指定方法,参数1是代理对象,参数2是参数类型,因为这里引用代理对象是无参方法,因此不填。
对构造方法使用任意类型进行接收,记得要强制转换。
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println(method.getName() + "方法开始执行");
Student result =(Student) method.invoke(this.obj, args);//执行指定的代理对象的指定方法
System.out.println(method.getName() + "方法执行完毕");
return result;
}
6.在test3类中创建接收ProxyDemo类的对象的InvocationHandler类型接口,括号里是被代理的对象,将其引入ProxyDemo类中的构造方法。
InvocationHandler Handler = new ProxyDemo(test);
//InvocationHandler负责管理所有方法的调用。
7.直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个iTestDemo接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,我们称为动态代码。返回的值
是成功被代理后的对象,由于JDK动态代理是基于接口实现的,因此要用接口去接收对象。(需要强转类型)
iTestDemo t = (iTestDemo) Proxy.newProxyInstance(Handler.getClass().getClassLoader(), test.getClass().getInterfaces(),Handler);
参数1是代理对象的类加载器;通过Handler.getClass获得代理对象的类,再.getClassLoader其加载器。
参数2是被代理对象的接口,用test.getInterfaces()获得。
参数3是代理对象也就是Handler。
8.调用构造方法运行代码。
t.test1();
t.test2();
程序运行:
test1方法开始执行
执行test1方法
test1方法执行完毕
test2方法开始执行
执行test2方法
test2方法执行完毕