代理模式 代理模式 是 设计模式中的结构类型相关设计模式 一般来说分为两种 静态代理 :继承 接口组合 针对于某个特殊的业务 具体定制对口代理 只能1对1 服务 动态地理 (代理模式):继承(CGLib) 接口组合(JDK自身代理) 为什么要用静态代理? 对于所有学生兑现给的调用方法前 需要添加日志记录 * 所有学生调用方法后 添加日志记录 * 此时添加日志的工作 和 本身的业务 没有任何关联关系 * 知识在业务的基础上添加了功能性代码 此时可以使用代理模式来处理功能和业务
一、静态代理
1、使用继承的方式来进行方法代理
public class Student {
/*
* 此处可以想象成一个复杂的业务方法
* */
public void study(){
System.out.println("开始学习");
}
}
/**
* 使用继承的方式来进行方法代理
*/
public class StudentProxy extends Student{
@Override
public void study() {
System.out.println("日志开启,开始执行");
//父类的核心业务方法
super.study();
System.out.println("执行结束,日志关闭");
}
}
//测试
public class ProxyDemo {
public static void main(String[] args) {
/*
* 对于所有学生兑现给的调用方法前 需要添加日志记录
* 所有学生调用方法后 添加日志记录
* 此时添加日志的工作 和 本身的业务 没有任何关联关系
* 知识在业务的基础上添加了功能性代码
*
* 此时可以使用代理模式来处理功能和业务
* */
Student stu = new StudentProxy();
stu.study();
}
}
2、接口组合实现代理
//创建接口
public interface Student {
void study();
}
//实现类
public class StudentInstance implements Student{
@Override
public void study() {
System.out.println("开始学习");
}
}
//代理类
public class StudentProxy implements Student {
//目标对象 -- 被代理类
private Student stu ;
public StudentProxy(Student stu){
this.stu =stu;
}
@Override
public void studay() {
System.out.println("日志开启,开始执行");
stu.study();
System.out.println("执行结束,日志关闭");
}
}
二、动态代理
此处使用JDK提供的动态代理来实现具体的代理过程
java.lang.reflect.Proxy
通过Proxy的 newProxyInstance 来实现动态代理类的类
由于JDK是基于接口实现的代理 所以目标对象和代理都需要使用同一接口
且还需要 InvocationHandler 接口 来描述代理的具体步骤
public interface Student {
void study(String name);
}
public class StudentIns implements Student {
@Override
public void study(String name) {
System.out.println(name+"开始认真学习");
}
}
public class StudentHandler implements InvocationHandler {
private Student stu ;
public StudentHandler(Student stu){
this.stu = stu;
}
/*
* 用来描述当前代理类中需要实现的具体内容
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("日志开启,开始执行");
method.invoke(stu,args);//原先的核心方法调用
System.out.println("执行结束,日志关闭");
return null;
}
}
/**
* 此处使用JDK提供的动态代理来实现具体的代理过程
* java.lang.reflect.Proxy
* 通过Proxy的 newProxyInstance 来实现动态代理类的类
* 由于JDK是基于接口实现的代理 所以目标对象和代理都需要使用同一接口
* 且还需要 InvocationHandler 接口 来描述代理的具体步骤
*/
public class DynamicProxyTest {
public static void main(String[] args) {
StudentHandler sh = new StudentHandler(new StudentIns());
Student stu = (Student)Proxy.newProxyInstance(StudentIns.class.getClassLoader(),
new Class[]{Student.class}, sh);
stu.study("张三");
}
}