讲解
代理模式概述
为什么要有“代理”?生活中就有很多代理的例子,例如,我现在需要出国,但是我不愿意自己去办签证、预定机票和酒店(觉得麻烦 ,那么就可以找旅行社去帮我办,这时候旅行社就是代理,而我自己就是被代理了。
代理模式的定义:被代理者没有能力或者不愿意去完成某件事情,那么就需要找个人代替自己去完成这件事,这个人就是代理者, 所以代理模式包含了3个角色: 被代理角色 代理角色 抽象角色(协议)
代码
// 协议
public interface FindHappy {
public abstract void happy();
}
// 被代理对象
public class JinLian implements FindHappy{
public void happy(){
System.out.println("金莲想要happy...");
System.out.println("金莲在happy...");
System.out.println("金莲happy完了...");
}
}
// 代理对象
public class WangPo implements FindHappy {
FindHappy fh;
public WangPo(FindHappy fh) {
this.fh = fh;
}
@Override
public void happy() {
System.out.println("王婆找到西门大官人沟通事项...");
System.out.println("王婆再以做衣服的名义把金莲和西门约到房间...");
// 金莲happy
fh.happy();
System.out.println("王婆打扫战场...");
}
}
测试
public class Test {
public static void main(String[] args) {
// 创建金莲对象
JinLian jl = new JinLian();
// jl.happy();
// 创建王婆代理对象
WangPo wp = new WangPo(jl);
wp.happy();
}
}
动态代理介绍
- 概述 : 动态代理就是在程序运行期间,直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
- 动态代理的获取:
jdk提供一个Proxy类可以直接给实现接口类的对象直接生成代理对象
动态代理相关api介绍
Java.lang.reflect.Proxy类可以直接生成一个代理对象
- Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一个代理对象
- 参数1:ClassLoader loader 被代理对象的类加载器
- 参数2:Class<?>[] interfaces 被代理对象的要实现的接口
- 参数3:InvocationHandler h (接口)执行处理类
- 返回值: 代理对象
- 前2个参数是为了帮助在jvm内部生成被代理对象的代理对象,第3个参数,用来监听代理对象调用方法,帮助我们调用方法
- InvocationHandler中的Object invoke(Object proxy, Method method, Object[] args)方法:调用代理类的任何方法,此方法都会执行
- 参数1:代理对象(慎用)
- 参数2:当前执行的方法
- 参数3:当前执行的方法运行时传递过来的参数
返回值:当前方法执行的返回值
案例演示
案例1: 代理方法无参数无返回值
public class Test {
public static void main(String[] args) {
/*
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一个代理对象
- 参数1:ClassLoader loader 被代理对象的类加载器
- 参数2:Class<?>[] interfaces 被代理对象的要实现的接口
- 参数3:InvocationHandler h (接口)执行处理类
- 返回值: 代理对象
- 前2个参数是为了帮助在jvm内部生成被代理对象的代理对象,第3个参数,用来监听代理对象调用方法,帮助我们调用方法
InvocationHandler中的Object invoke(Object proxy, Method method, Object[] args)方法:调用代理类的任何方法,此方法都会执行
- 参数1:代理对象(慎用)
- 参数2:当前执行的方法(代理对象调用的方法)
- 参数3:当前执行的方法运行时传递过来的参数
- 返回值:当前方法执行的返回值
*/
// 被代理对象
JinLian jl = new 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 {
// 代理对象调用方法就会来到这个invoke方法里面
System.out.println("王婆以做头发的名义把人约到开好的方法里...");
// jl.happy();
method.invoke(jl,args);
System.out.println("王婆打印卫生...");
return null;
}
});// 返回的是代理对象
proxy.happy();
}
}