接口类
public interface UserService {
void queryUsers();
}
实现类
public class UserServiceImp implements UserService {
@Override
public void queryUsers() {
System.out.println("用户查询");
}
}
代理类
public class UserServiceJdkProxy implements InvocationHandler {
// 代理的目标对象
private Object target;
public UserServiceJdkProxy(Object target) {
this.target = target;
}
/** 创建代理对象 */
public Object createInstance(){
// 第1个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
// 第2个参数设置代理类实现的接口
// 第3个参数设置回调对象,当代理对象的方法被调用时,会调用该参数指定对象的invoke方法
return Proxy.newProxyInstance(
getClass().getClassLoader(), // 第1个参数
target.getClass().getInterfaces(), // 第2个参数
this // 第3个参数
);
}
/**
* @param proxy 目标对象的代理类实例
* @param method 对应于在代理实例上调用接口方法的Method实例
* @param args 传入到代理实例上方法参数值的对象数组
* @return 方法的返回值,没有返回值(void)时是null
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("开始用户查询");
Object result = method.invoke(target, args); // 执行原方法,把方法调用委派给目标对象
System.out.println("用户查询结束");
return result;
}
}
测试类
public class test {
@Test
public void testName() throws Exception {
// 原对象
UserService userService = new UserServiceImp();
// 创建代理对象
userService = (UserService) new UserServiceJdkProxy(userService).createInstance();
// 执行方法(使用的是代理对象)
userService.queryUsers();
}
}
执行结果:
开始用户查询
用户查询
用户查询结束
JDK动态代理总结:
1, JAVA动态代理是使用java.lang.reflect包中的Proxy类与InvocationHandler接口这两个来完成的。
2, 要使用JDK动态代理,必须要定义接口。
3, JDK动态代理将会拦截所有pubic的方法(因为只能调用接口中定义的方法),这样即使在接口中增加了新的方法,不用修改代码也会被拦截。
4, 如果只想拦截一部分方法,可以在invoke方法中对要执行的方法名进行判断。