今天呢。我们来学习意向JDK的动态代理
也可以使用JDK的API实现动态代理。这种方式要求目标类有一个接口。这种方式也叫做JDK代理或接口代理。
1、代理类
使用前面静态代理一节的 UserService 和 UserServiceImpl
2、创建代理工厂
package com.qfedu.proxy.utils;
public class ProxyFactoryJDK {
/**
* 目标对象
*/
private Object target;
public ProxyFactoryJDK(Object target) {
this.target = target;
}
//给目标对象生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),//指定当前目标对象使用类加载器
target.getClass().getInterfaces(),//目标对象的接口类型
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置通知。。。。。。");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("后置通知。。。。。。");
return returnValue;
}
}
);
}
}
JDK实现代理只需要使用newProxyInstance方法,此方法需要三个参数
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
这个方法是静态方法,参数分别为:
ClassLoader loader 指定当前目标对象使用类加载器
Class<?>[] interfaces 目标对象实现的接口的类型
InvocationHandler h 事件处理器,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
3、测试
/**
- 测试JDK动态代理
*/
@Test
public void test03(){
//创建目标对象
UserService userService = new UserServiceImpl();
//创建代理工厂
ProxyFactoryJDK proxyFactory = new ProxyFactoryJDK(userService);
//从代理工厂或得动态代理类
UserService userService1Proxy = (UserService)proxyFactory.getProxyInstance();
//调用代理的代理方法
userService1Proxy.save();
}
总结:
如果目标对象有接口,用JDK代理
如果目标对象没有接口,用Cglib代理