代理
代理: 就是让代理角色帮助真实角色完成一件事情;
比如我们生活中比较熟悉的代购、中介、商家等都是属于代理
静态代理
/*
静态代理,动态代理----都属于代理设计模式,让代理角色帮助真实角色完成一个事情;
从代码角度去讲:将业务代码和系统监控相关代码(权限校验,系统日志的产生)进行分离;
静态代理:
特点:
代理角色和真实角色需要实现同一个接口;回想多线程的实现方式第二种
*/
class MyRunnable implements Runnable{
public void run(){
//..
//完成耗时的操作
}
}
//本身Thread类
class Thread implements Runnable{
private Runnable target ;
public Thread(Runnable target){
//初始化的操作
}
//重写run方法
public void run(){
if(target !=null){
target.run() ;
}
}
}
静态代理原理:
在编译时就已经将接口、被代理类、代理类等确定下来,程序运行之前,代理类的.class文件就已经生成。
使用静态代理时,代理对象与目标对象要实现相同的接口,以此来保证两者具有相同的方法。
静态代理优点:
结构简单,容易连接。能够在不修改目标对象的基础上,实现功能扩展。
动态代理
/*jdk动态代理: 使用反射的方式,在程序执行过程中产生代理对象---->利用反射调用接口中的方法,前提条件
必须基于接口,才能完成jdk动态代理;
*/
//java.lang.reflect.Proxy 代理
public static Object newProxyInstance(ClassLoader classloader,Class[] interfaces,InvocationHandler handler)
//在第三个参数InvocationHandler:基于代理的处理程序---需要调用我们接口的方法
/**
* @author Kuke
* @date 2022/5/16
* 针对用户访问的数据接口
*/
public interface UserDao {
/**
* 添加功能
*/
void add() ;
/**
* 修改功能
*/
void update() ;
/**
* 查询功能
*/
void select() ;
/**
* 删除功能
*/
void delete() ;
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author Kuke
* @date 2022/5/16 11:26
* 基于代理的处理程序
*/
public class MyInvocationhandler implements InvocationHandler {
//要针对谁产生代理: ud UserDao ud = new UserDaoImpl() ;
private Object target ; //因为代理角色可以是任意Java类型,所
// 以用Object
public MyInvocationhandler(Object target){
this.target = target ;
}
//方法的返回值就是代理对象
@Override //就是我们的接口的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("权限校验") ;
//调用接口的列表自己的方法:update(),delete(),add(),select()
//当前实例--->真实角色
Object obj = method.invoke(target, args); //调用方法产生的返回值
System.out.println("产生日志文件");
return obj;
}
}
//测试类
public class JdkProxyDemo {
public static void main(String[] args) {
//接口多态:测试UserDao
UserDao ud = new UserDaoImpl() ; //真实角色
//版本1:现在需要对功能增强,这个代码不合适!
ud.add();
ud.update();
ud.select();
ud.delete();
System.out.println("----------------Jdk动态代理------------------");
//前提示需要一个接口:UserDao
MyInvocationhandler handler = new MyInvocationhandler(ud) ;
// public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
//代理角色proxyInstance
UserDao proxyInstance = (UserDao) Proxy.newProxyInstance(
ud.getClassLoader(),
ud.getClass().getInterfaces(),
handler);
proxyInstance.add();
proxyInstance.update();
proxyInstance.select();
proxyInstance.delete();
}
}
两者区别
静态代理只代理一个类,而动态代理是代理接口下的多个实现类;
静态代理在编译时就知道要代理的类,而动态代理是在运行期动态生成的代理类;
动态代理类不需要实现接口,但是委托类还是需要实现接口。