JDK动态代理:
1:jdk动态代理是指在运行时动态的创建被代理类的接口的子类。
2:再通过反射调用被代理的类方法。
3:jdk动态代理可以在用户没有感觉的情况下,渗入到被代理的方法去执行。(Spring中的AOP思想)
4:只对一个方法不拦截,getClass()
要求:
1:jdk动态代理中所有的被代理的类,都必须要拥有一个接口。没有接口的类,无法被动态代理。
除了jdk代理还有cglib代理,cglib不需要接口就可以实现动态代理,这两种在Spring中都可以
以下是一个最基本的JDK动态代理示例:
在JDK中一个类:有两个核心类:
1:Proxy – 用于在运行时创建被代理类的接口的子类。
2:InvocationHandler – 在执行时拦截被代理类的方法。 执行句柄。
第一步:
/**
* 声明一个接口
* @author zfx
*/
public interface IPerson {
String run();
}
第二步:
/**
* 被代理类
*/
public class Person implements IPerson {
public String run(){
System.err.println("正在跑步.....");
return "run....";
}
}
第三步:
@Test
public void test2(){
//1:声明被代理类
final Person p = new Person();
System.err.println("1:声明被代理类:"+p+",类名是:"+p.getClass());
//2:通过Proxy类的静态方法,在内存中动态的创建IPerson接口的子类
Object proxyObj = Proxy
.newProxyInstance(TestUserProxy.class.getClassLoader(),
new Class[]{IPerson.class},
new InvocationHandler() {//匿名内部类
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//3:输出用户正在调用的方法
System.err
.println("4:正在调用的方法名为:"+method.getName());
//4:执行目标类的方法,接收返回值
Object returnValue = method.invoke(p,args);
System.err
.println("6:目标方法调用完成,返回值是:"+returnValue);
return returnValue;
}
});
System.err.println("2:创建了被代理类它是:"+proxyObj.getClass());
//5:将proxyobj转成Iperson接口
IPerson p3 = (IPerson) proxyObj;
System.err.println("3:转换成功,开始调用");
//6:调用了代理类的run方法
String str = p3.run();
System.err.println("7:调用完成>");
}
Junit执行结果:
1:声明被代理类:cn.zfx.demo4.proxy.Person@276baafc,类名是:class cn.zfx.demo4.proxy.Person
2:创建了被代理类它是:class com.sun.proxy.$Proxy4
3:转换成功,开始调用
4:正在调用的方法名为:run
正在跑步.....
6:目标方法调用完成,返回值是:run....
7:调用完成>