代理的概述
为什么要有“代理”?生活中就有很多例子,例如委托业务等等,代理就是被代理者没有能力或者不愿意去完成某件事情,需要找个人代替自己去完成这件事,这才是“代理”存在的原因。例如,我现在需要出国,但是我不愿意自己去办签证、预定机票和酒店(觉得麻烦 ,那么就可以找旅行社去帮我办,这时候旅行社就是代理,而我自己就是被代理了。
1.代理模式概述
1.1什么是代理模式
ProxyPattern(即:代理模式),23种常用的面向对象软件的设计模式之一
代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
作用:增强一个类中的某个方法.对程序进行扩展.
1.2动态代理介绍
动态代理它可以直接给某一个目标(被代理 对象)对象(实现了某个或者某些接口)生成一个代理对象,而不需要代理类存在。
动态代理与代理模式原理是一样的,只是它没有具体的代理类,直接通过反射生成了一个代理对象。
-
动态代理的获取:
jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象
2.jdk中的动态代理的使用
2.1API介绍
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:当前执行的方法运行时传递过来的参数
- 返回值:当前方法执行的返回值
2.2代码实现
//抽象接口 被代理者和代理者要实现的抽象方法
public interface FindHappy{
void happy();
}
//被代理人
public class JinLian implements FindHappy{
public void happy(){
System.out.println("金莲happy...");
}
}
public class Demo {
public static void main(String[] args) {
/*
动态代理:可以直接生成一个代理对象 ,不需要创建代理类
Java.lang.reflect.Proxy类: 表示代理
作用:Proxy类中提供了很多静态方法,可以动态的生成一个代理对象
静态方法:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 动态生成一个类的代理对象
参数1loader: 表示被代理类的类加载器 被代理类的字节码对象.getClassLoader()
参数2interfaces: 表示被代理类实现的所有接口的数组 被代理类的字节码对象.getInterfaces()
以上这2个参数,就是为了动态生成一个代理对象
参数3InvocationHandler: 执行处理接口,传入InvocationHandler实现类,用来执行代理对象要执行的方法
参数3为了执行代理对象调用的方法
InvocationHandler接口中的方法;
public Object invoke(Object proxy, Method method, Object[] args){}
1. 但凡是代理对象调用方法就会执行InvocationHandler中invoke方法
2. invoke方法中的参数1 proxy: 表示动态生成的代理对象,注意,在invoke方法里面不要使用proxy调用方法,否则会栈内存溢出错误
3. invoke方法中的参数2 method: 表示代理对象调用的方法
4. invoke方法中的参数3 args: 表示代理对象调用的方法 传入的实参
5. invoke方法中的返回值类型: 表示代理对象调用的方法的 返回值类型
*/
JinLian jinLian = new JinLian();
// 使用动态代理模式生成JinLian的代理对象:
FindHappy proxy = (FindHappy) Proxy.newProxyInstance(JinLian.class.getClassLoader(), JinLian.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("王婆以做头发的名义把房间开好了...");
method.invoke(jinLian);
System.out.println("happy完后,王婆打扫战场...");
return null;
}
});
System.out.println("呵呵呵");
proxy.happy();// 代理对象执行happy方法
System.out.println("嘿嘿嘿");
}
}
"D:\Program Files\Java\jdk1.8.0_291\bin\java.exe" -javaagent:D:\soft\ideaIC-2022.2.win\lib\idea_rt.jar=63164:D:\soft\ideaIC-2022.2.win\bin -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_291\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_291\jre\lib\rt.jar;E:\projects\sifang-master\demo\target\classes;D:\maven\repository\org\springframework\boot\spring-boot-starter\2.3.0.RELEASE\spring-boot-starter-2.3.0.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot\2.3.0.RELEASE\spring-boot-2.3.0.RELEASE.jar;D:\maven\repository\org\springframework\spring-context\5.2.6.RELEASE\spring-context-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-logging\2.3.0.RELEASE\spring-boot-starter-logging-2.3.0.RELEASE.jar;D:\maven\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\maven\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\maven\repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\maven\repository\org\apache\logging\log4j\log4j-to-slf4j\2.13.2\log4j-to-slf4j-2.13.2.jar;D:\maven\repository\org\apache\logging\log4j\log4j-api\2.13.2\log4j-api-2.13.2.jar;D:\maven\repository\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;D:\maven\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;D:\maven\repository\org\springframework\spring-core\5.2.6.RELEASE\spring-core-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-jcl\5.2.6.RELEASE\spring-jcl-5.2.6.RELEASE.jar;D:\maven\repository\org\yaml\snakeyaml\1.26\snakeyaml-1.26.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-web\2.3.0.RELEASE\spring-boot-starter-web-2.3.0.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-json\2.3.0.RELEASE\spring-boot-starter-json-2.3.0.RELEASE.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.0\jackson-datatype-jdk8-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.0\jackson-datatype-jsr310-2.11.0.jar;D:\maven\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.0\jackson-module-parameter-names-2.11.0.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-tomcat\2.3.0.RELEASE\spring-boot-starter-tomcat-2.3.0.RELEASE.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.35\tomcat-embed-core-9.0.35.jar;D:\maven\repository\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.35\tomcat-embed-websocket-9.0.35.jar;D:\maven\repository\org\springframework\spring-web\5.2.6.RELEASE\spring-web-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-beans\5.2.6.RELEASE\spring-beans-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-webmvc\5.2.6.RELEASE\spring-webmvc-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-aop\5.2.6.RELEASE\spring-aop-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-expression\5.2.6.RELEASE\spring-expression-5.2.6.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-autoconfigure\2.3.0.RELEASE\spring-boot-autoconfigure-2.3.0.RELEASE.jar" com.sifang.Demo
呵呵呵
王婆以做头发的名义把房间开好了...
金莲happy...
happy完后,王婆打扫战场...
嘿嘿嘿
Process finished with exit code 0