1.何为代理模式
如果从业务角度来讨论,就是将主要业务和次要业务解耦合,让开发人员只需要专注主要业务的开发即可,mybatis是代理模式最好的体现,开发人员只需要专注sql开发,jdbc连接都交由代理自动处理
2.代理模式相关对象
- 接口:声明需要被监听的的行为
- 真实实现类:实现主要业务行为
- 代理实现类(InvocationHandler):将次要业务和主要业务绑定执行
- 代理对象(监听对象)
3.简单应用例子
场景:上下班都需要打卡
主要业务:上班、下班
次要业务:打卡
代码实现
接口类:
public interface SbService {
public void onWork(String name);//上班
public void offWork(String name);//下班
}
真实实现类:
public class Person implements SbService {
@Override
public void onWork(String name) {
System.out.println(name+"在XXX公司上班");
}
@Override
public void offWork(String name) {
System.out.println(name+"在XXX公司下班");
}
}
代理实现类:
//实现InvocationHandler接口
public class Agent implements InvocationHandler {
private SbService obj;// 传入的真实对象
//完成次要业务和主要业务绑定
public Agent(SbService param) {
this.obj = param;
}
/*
* Object proxy:本次负责监听对象
*
* Method method: 被拦截的主要业务方法
*
* Object[] params:被拦截的主要业务方法接受的实参
*
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
//1.读取被拦截的方法名称
String methodName =method.getName();
if("onWork".equals(methodName)){//上班打卡
card();//上班前打卡
method.invoke(obj, params);
}else if("offWork".equals(methodName)){//下班打卡
method.invoke(obj, params);
card();//下班后打卡
}
return null;
}
//次要业务
private void card(){
System.out.println("打卡");//解耦合;
}
}
代理对象:
public class ProxyFactory {
public static SbService newInstance(){
}
public static SbService newInstance(Class classFile) throws InstantiationException, IllegalAccessException{
//0.创建被索要的类型的实例对象
SbService 真实对象 = (SbService) classFile.newInstance();
//1.让真实对象拥有一个代理实现类对象
InvocationHandler agent = new Agent(真实对象);
//2.申请/注册一个对特定行为进行监控对象(代理对象)
/*
* loader:指向被监控的类文件在内存中真实地址
* interfaces: 被监控的类所实现的接口,这个接口中声明的方法,就是需要被监控行为
* 也是主要业务行为名称
* */
Class classArray[]={SbService.class};
SbService 监听对象=(SbService) Proxy.newProxyInstance(classFile.getClassLoader(), classArray, agent);
return 监听对象;
}
}
测试:
public class TestMain {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
SbService sb = ProxyFactory.newInstance(Person.class);
sb.onWork("小红");
sb.offWork("小红");
}
}
结果:
打卡
小红在XXX公司上班
小红在XXX公司下班
打卡