代理模式(Proxy)
代理模式分为两种:一种是静态代理;一种是动态代理,因为静态代理存在的问题太多及不方便操作,现在使用的多数是动态代理,所以今天说的就是关于动态代理的一些基本.
- 动态代理:指的是不用自己手动创建代理对象,通过Proxy类动态创建代理对象
- 作用:拦截对真实对象的访问,对真实对象的功能进行增强
/*通过调用Proxy类的下面的方法创建代理对象*/
static Object newProxyInstrance(classLoader loader,interfaces,h)
/*方法的几个参数的含义
- loader:传递的是真实对象的构造器
- (方法创建代理对象的时候,内部是会生成一个代理类返回的,这个类需要知道被代理对象的一些具备的行为)
- interfaces: 真实对象(被代理对象)实现的所有接口
- (代理对象也需要具备被代理对象的功能)
- h:回调处理对象(这个后面再讲,回调处理对象的作用就是为了拦截代理对象调用功能,再拦截功能后执行真实对象的功能,以至于做到代理对象调用功能的假象)
----------
回调处理对象:创建一个类去继承(invocationHandler接口),并且重写public Object invoke(Object proxy,Method method,Object[]args)方法
|-该方法的作用是,当每次代理对象调用的时候会触发该方法的调用,用于拦截方法,执行此方法
|-proxy:代理对象
|-method:对象调用的方法,拦截到方法
|-agrs:代理对象调用方法时传递的参数
|-返回值:一般返回真实对象执行后的结果
/*现有一个数据访问层类(StudentDao),类中提供了对学生进行增删改查的方法。
- 现有一个业务层类(StudentService),该类需要调用StudentDao类中定义好的方法对学生进行增删改查操作。
- 要求:在调用StudentDao方法之前要先判断用户是否有权限
- 如果有权限则允许调用StudentDao方法,并在调用完StudentDao方法之后要记录日志。
- 如果没有权限则不允许调用StudentDao方法。
- **不允许修改StudentDao类中代码实现以上需求。**
- **数据访问层类StudentDao** */
public class StudentDao implements Dao<Student>{
@Override
public void save(Student t) {
System.out.println("增加学生信息:" + t);
}
@Override
public void delete(Student t) {
System.out.println("删除学生信息:" + t);
}
@Override
public void update(Student t) {
System.out.println("更新学生信息:" + t);
}
@Override
public Student find(int id) {
System.out.println("查询学生信息");
Student s = new Student();
System.out.println(s);
return s;
}
}
- /* 业务层类StudentService */
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class StudentSerivce {
public static void main(String[] args) {
// 创建StudentDao对象
// 被代理对象(真实对象)
StudentDao stuDao = new StudentDao();
// 创建学生对象
Student stu = new Student();
// 创建代理对象
Dao proxy = (Dao)Proxy.newProxyInstance(StudentDao.class.getClassLoader(),
StudentDao.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(check(method)) {
// 如果有权限,则调用真实对象的方法
Object result = method.invoke(stuDao, args);
// 记录日志
log();
// 返回结果
return result;
} else {
// 没有权限不调用真实对象的方法
}
return null;
}
/**
* 记录日志
*/
private void log() {
System.out.println("记录日志");
}
/**
* 检查是否有权限
*/
public boolean check(Method method) {
if(method.getName().equals("find")) return true;
return false;
}
});
// 通过代理对象调用方法
proxy.save(stu);
proxy.update(stu);
proxy.delete(stu);
Student s = (Student) proxy.find(1);
System.out.println("ss = " + s);
}
// 自定义回调处理对象
public static void test02(String[] args) {
// 创建StudentDao对象
// 被代理对象(真实对象)
StudentDao stuDao = new StudentDao();
// 创建学生对象
Student stu = new Student();
// 创建回调处理对象
MyInvocationHandler handler = new MyInvocationHandler(stuDao);
// 创建代理对象
Dao proxy = (Dao)Proxy.newProxyInstance(StudentDao.class.getClassLoader(),
StudentDao.class.getInterfaces(), handler);
// 通过代理对象调用方法
proxy.save(stu);
proxy.update(stu);
proxy.delete(stu);
Student s = (Student) proxy.find(1);
System.out.println("ss = " + s);
}