代理模式:
1:代理概念:
代理模式分为两种,一种是静态代理模式,一种是动态代理模式。
静态代理模式:在程序运行之前需要写好代理类
动态代理模式:在程序运行期间动态生成代理类(利用反射进行创建一个静态代理类)
2:静态代理的实现:
想要理解动态代理类线了解静态代理类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wq5Gxper-1631698173414)(C:\Users\6346566\AppData\Roaming\Typora\typora-user-images\image-20210727173132929.png)]
/**
* 创建Person接口
* @author Gonjan
*/
public interface Person {
//上交班费
void giveMoney();
}
/**
*实现接口类
*/
public class Student implements Person {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public void giveMoney() {
System.out.println(name + "上交班费50元");
}
}
/**
* 学生代理类,也实现了Person接口,保存一个学生实体,这样既可以代理学生产生行为
* @author Gonjan
*
*/
public class StudentsProxy implements Person{
//被代理的学生
Student stu;
public StudentsProxy(Person stu) {
// 只代理学生对象
if(stu.getClass() == Student.class) {
this.stu = (Student)stu;
}
}
//代理上交班费,调用被代理学生的上交班费行为
public void giveMoney() {
stu.giveMoney();
System.out.println("静态代理");//加入了其他的操作
}
}
public class StaticProxyTest {
public static void main(String[] args) {
//被代理的学生张三,他的班费上交有代理对象monitor(班长)完成
Person zhangsan = new Student("张三");
//生成代理对象,并将张三传给代理对象
Person monitor = new StudentsProxy(zhangsan);
//班长代理上交班费
monitor.giveMoney();
}
}
静态代理类:思想主要是将实现类对象交由代理类创建出代理类对象,中间的代理类就可以在必须实现实现类需要做的方法的同时,在方法中加入一些不一样的操作;
3:动态代理类
//接口类
public interface A {
void print();
}
//实现类
public class B implements A{
@Override
public void print() {
System.out.println("hello");
}
}
//处理类
public class Invocation implements InvocationHandler {
private Object object;
public Invocation(Object object) {
this.object=object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy:就是代理对象
//method:调用的方法
//args: 方法中的参数
Object result = method.invoke(object,args);
System.out.println("hi");
return result;//返回该方法的返回值
}
}
//测试类
public class test {
public static void main(String[] args) {
B b = new B();
Invacation p = new Invocation(new B());//将实现类对象交由处理类
//由处理类动态创建一个代理类(反射)
A a = (A) Proxy.newProxyInstance(b.getClass().getClassLoader(), B.class.getInterfaces(), p);
//第一个参数是应用类加载器(用哪个类都可以去获取类加载器,程序使用的基本都是应用类加载器:另见笔记)
//第二个参数是实现类的实现了的接口
//第三个参数是需要处理的类对象(创建该对象时需要把需要处理的类的对象传进去)
a.print();
}
}
动态代理思想:就是将实现类交由处理类,处理类就可以添加一些扩展功能,再由Proxy.newProxyInstance(b.getClass().getClassLoader(), B.class.getInterfaces(), p)创建出相应代理类注意:此代理类还是一个Object对象,需要转型为接口对象;
注意异常:
//方法内部的异常在invoke方法中都被打包成InvocationException,需要用getCase方法抛出对应的异常
Object result = method.invoke(object,args);
所以需要改成
try {
pro = method.invoke(object, args);
}catch (Exception e ){
throw e.getCause();
}
//抛出Throwable
要改成
try {
pro = method.invoke(object, args);
}catch (Exception e ){
throw e.getCause();
}
//抛出Throwable