目录
- 首先在接口中定义一个行为
- 再定义一个目标角色实现接口,实现行为
- 去代理角色类中解决一下报错,但是什么都不要写
invoke的return返回的值是调用方法中返回的值
下面我们来实例看一下
首先在接口中定义一个行为
public String toMarry02();
再定义一个目标角色实现接口,实现行为
注意这里return了一个字符串hi
@Override
public String toMarry02(){
System.out.println("二婚");
return "hi";
}
去代理角色类中解决一下报错,但是什么都不要写
@Override
public String toMarry02() {
return null;
}
这个时候在获取代理对象的invoke方法中return null,不要return object
package com.svt.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK动态代理类
* 每一个代理类都需要实现InvocationHandler接口
*/
public class JdkHandler implements InvocationHandler {
//目标对象
private Object target;//类型不固定,创建时动态生成
//通过带参构造器传递目标对象
public JdkHandler(Object target) {
this.target = target;
}
/**
* 1.调用目标对象的方法(返回object)
* 2.增强目标对象的行为
*
* @param proxy 调用该方法的代理实例
* @param method 目标对象的方法
* @param args 目标对象的方法所需要的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前后都可能会有增强行为,不一定都要有,只是可能会有
//用户的增强行为
System.out.println("============方法执行前");
// 调用目标对象中的方法(返回object)
Object object=method.invoke(target,args);
//用户的增强行为
System.out.println("方法执行后============");
return null;//调用方法中返回的值
}
/**
* 获取代理对象
* public static Object newProxyInstance(ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h)
* Loader:类加载器
* interfaces:接口数组
* target.getClass().getInterfaces():目标对象的接口数组
* h:InvocationHandler接口(传入InvocationHandler接口的实现类)
* @return
*/
public Object getProxy(){
Object object= Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
return object;
}
}
在测试类中进行测试
public class JdkHandlerTest {
public static void main(String[] args) {
//目标对象
You you = new You();
//得到代理类
JdkHandler jdkHandler = new JdkHandler(you);
//得到代理对象
Marry marry = (Marry) jdkHandler.getProxy();
//通过代理对象调用目标对象的方法
String msg = marry.toMarry02();
System.out.println(msg);
}
}
得到的结果是初始化了,但是没有返回值,因为我们将invoke中的返回值写成了null,所以不管在目标角色里写多少返回值都不会出现在控制台
这个时候我们只要将获取代理对象的invoke方法中return null改为return object,就能将结果呈现在控制台
这就是获取代理对象的invoke方法中return object的用处,最好写成return object哦!