代理模式
为什么需要学习代理模式?->>>AOP的底层机制为动态代理
- 静态代理
- 动态代理
静态代理
-
静态代理角色分析:
抽象角色 : 一般使用接口或者抽象类来实现
真实角色 : 被代理的角色
代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .
客户 : 使用代理角色来进行一些操作 . -
静态代理的好处:
可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
公共的业务由代理来完成 . 实现了业务的分工 ,
公共业务发生扩展时变得更加集中和方便 .
缺点 :类多了 , 代理类多了 , 工作量变大了 . 开发效率降低 .
我们想要静态代理的好处,又不想要静态代理的缺点,所以 , 就有了动态代理 !
动态代理
动态代理可以理解为动态方法增强,即我们可以在调用原方法的前后做一些事情。
- 动态代理的角色和静态代理的一样 .
- 动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
- 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
这边用到两个类的两个方法。
- Proxy.newProxyInstance();
- InvocationHander.invoke();
定义接口:
package com.eddievim.invocation;
//定义接口
public interface People {
public void say();
}
定义实现类:
package com.eddievim.invocation;
public class Teacher implements People {
@Override
public void say() {
System.out.println("teacher");
}
}
定义hander,方法调用处理器:
package com.eddievim.invocation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHander implements InvocationHandler {
//被代理的类
Object object;
public MyInvocationHander(Object object) {
this.object = object;
}
@Override
//新的代理类调用方法时,会跳转到这里执行
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法前 执行
System.out.println("方法执行前");
//执行原来的方法
Object invoke = method.invoke(object, args);
//方法后 执行
System.out.println("方法执行后");
return invoke;
}
}
测试:
package com.eddievim.invocation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
//先创建代理对象
People people = new Teacher();
//创建方法调用处理器
InvocationHandler handler = new MyInvocationHander(people);
//获取代理类
People proxy = (People)Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler);
//代理类调用方法
proxy.say();
}
}
debug:
根据debug的结果,我们可以看到,最终的代理就是装下了一个hander,所以我们可以猜测,代理类调用方法时,就会调用hander中的invoke。
相关思维导图: