1.代理
1.1概述
1.1.1什么是代理
ProxyPattern(即:代理模式),23种常用的面向对象软件的设计模式之一
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
作用:增强一个类中的某个方法.对程序进行扩展.Spring框架中AOP.
1.1.2动态代理
动态代理它可以直接给某一个目标(被代理 对象)对象(实现了某个或者某些接口)生成一个代理对象,而不需要代理类存在。
动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。
1.2动态代理分类
jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象 API: 调用, 缺少什么参数,传什么
spring中动态代理:cglib 继承
2.jdk中的动态代理
👍自己体会
以下案例重点看:if("run".equals(method.getName())),此语句修改run,stop,addOil输出什么结果,修改的同时可以修改调用语句如:proxyCar.run();
packagecom.libin.proxy;
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
importorg.junit.Test;
publicclassDynamicTest{
@Test
publicvoidfun01(){
finalQqqq=newQq();
//使用动态代理,产生Qq的代理(增强)对象 ; 缺少什么参数传什么
//参数一: 类加载器
//参数二: 传被代理类实现的接口的class类型 (new Class[]{Car.class})
//参数三: 处理器(当前代理对象执行的方法全部由处理器控制)
//返回值: 就是代理(增强)对象
CarproxyCar=(Car)Proxy.newProxyInstance(qq.getClass().getClassLoader(),qq.getClass().getInterfaces(),newInvocationHandler() {
//代理对象方法执行一次 invoke就会执行一次, 其实就是invoke来控制方法调用
//参数1: 代理对象(慎用)
//参数2: 当前执行的方法对应的对象
//参数3: 当前方法传的参数
//返回值: 就是当前方法的返回值
@Override
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
if("run".equals(method.getName())){
//拿到方法名,增强stop方法
System.out.println("5s破百");
//调用原来的stop方法,如果不想要原来的方法就不调用
Objectinvoke=method.invoke(qq,args);
returnnull;
}
//如果不成立,那么就是其他的方法,如run方法或addOil方法
Objectinvoke=method.invoke(qq,args);
//返回run方法
returninvoke;
}
});
//从Override开始到此处,需要增强的方法写在里面,
//下面的方法用于调用以上的重写方法
//proxyCar.run();//执行结果:5s破百 Qq 可以跑60迈...
//proxyCar.stop();//执行结果:Qq 可以刹车... 为什么是这个结果,因为stop没有进入if循环进行方法增强,只调用了原来的方法
StringaddOil=proxyCar.addOil(9);
//注意此处没输出,因为原来的(Qq类)方法没直接输出,需要自己写输出语句
System.out.println(addOil);//执行结果: Qq车加9#油~~~
}
classQqimplementsCar{
@Override
publicvoidrun() {
System.out.println("Qq 可以跑60迈...");
}
@Override
publicvoidstop() {
System.out.println("Qq 可以刹车...");
}
@Override
publicStringaddOil(intnum) {
return"Qq车加"+num+"#油~~~";
}
}
interfaceCar{
voidrun();
voidstop();
StringaddOil(intnum);
}
}
Java.lang.reflect.Proxy类可以直接生成一个代理对象
Proxy.newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)生成一个代理对象
参数1:ClassLoader loader 代理对象的类加载器 一般使用被代理对象的类加载器
参数2:Class[] interfaces 代理对象的要实现的接口 一般使用的被代理对象实现的接口
参数3:InvocationHandler h (接口)执行处理类
InvocationHandler中的invoke(Object proxy, Method method, Object[] args)方法:调用代理类的任何方法,此方法都会执行
参数3.1:代理对象(慎用)
参数3.2:当前执行的方法
参数3.3:当前执行的方法运行时传递过来的参数
返回值:当前方法执行的返回值
Eg:
packagecom.itheima.proxy.dynamic;
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
importorg.junit.Test;
publicclassDemo01{
@Test
publicvoidfun01(){
finalQqqq=newQq();
Carcar=(Car)Proxy.newProxyInstance(qq.getClass().getClassLoader(),qq.getClass().getInterfaces(),newInvocationHandler() {
@Override
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
if("run".equals(method.getName())){
System.out.println("QQ加了鸡血可以跑100迈...");
returnnull;
}
Objectresult=method.invoke(qq,args);
System.out.println("result="+result);
return"哈哈哈";
}
});
//car.run();
Stringstr=car.addOil(93);
System.out.println("str="+str);
}
interfaceCar{
voidrun();
voidstop();
StringaddOil(intnum);
}
classQqimplementsCar{
@Override
publicvoidrun() {
System.out.println("Qq可以跑60迈...");
}
@Override
publicvoidstop() {
System.out.println("Qq刹车....");
}
@Override
publicStringaddOil(intnum) {
return"qq加"+num+"号油...";
}
}
}
三,思路分析
网友评论