代理模式
- 静态代理 : 代理类是提前写好的
- 动态代理 : 代理类是动态生成的
静态代理中一个真实角色就会产生一个代理对象,当代理对象多了之后,代码量会翻倍,开发效率会降低,所以要使用动态代理
动态代理可以代理多个类,代理的是接口!
动态代理:
- 基于接口的动态代理—Jdk动态代理
- 基于类的动态代理—cglib动态代理
下面主要讲的是JDK动态代理,需要用到 InvocationHandler 接口 ,Method 类 ,
Proxy 类
**
1. InvocationHandler接口
**
InvocationHandler接口叫做调用处理器,负责完成调用目标方法,并增强功能,通过代理对象(Proxy创建)执行目标接口中的方法,会把方法的调用分派给调用处理器(InvocationHandler)的实现类,执行实现类中的invoke方法,我们要把加强的功能写在invoke方法中.
/**
* 处理代理实例上的方法 并返回结果
* @param proxy:代表生成的代理对象 调用该方法的代理实例
* @param method:代表目标方法
* @param args:目标方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
2. Method类
Method 类
上述invoke()方法的第二个参数为 Method 类对象,该类有一个方法也叫 invoke(),可以调用
目标方法。这两个 invoke()方法,虽然同名,但无关。
public Object invoke ( Object obj, Object... args)
obj:表示目标对象
args:表示目标方法参数,就是其上一层 invoke 方法的第三个参数
3 . Proxy 类
通 过 JDK 的 java.lang.reflect.Proxy 类 实 现 动 态 代 理 , 会 使 用 其 静 态 方 法
newProxyInstance(),依据目标对象、业务接口及调用处理器三者,自动生成一个动态代理对象
public static newProxyInstance ( ClassLoader loader, Class<?>[] interfaces,
InvocationHandler handler)
loader:目标类的类加载器,通过目标对象的反射可获取
interfaces:目标类实现的接口数组,通过目标对象的反射可获取
handler:调用处理器。
4. 步骤
1、新建一个接口,作为目标接口
2、为接口创建一个实现类,是目标类 (到这边都和之前的代码步骤是一样的)
3、创建类实现InvocationHandler 接口,调用目标方法并增加其他功能代码
4、创建动态代理对象,使用 Proxy.newProxyInstance()方法,并把返回值强制转为接口类型
package com.kuang.demo3;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口可是任意形式
private Object target;
public void setTarget(Object target) {
//使用构造方法传入目标对象,给目标对象提供代理功能
this.target = target;
}
//生成得到代理类 这里将生成代理类自己接封装进了该类中
public Object getProxy(){
/**
* this在这就是调用处理器对象
*/
Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
return proxy;
}
/**
* 处理代理实例上的方法 并返回结果
* @param proxy:代表生成的代理对象 调用该方法的代理实例
* @param method:代表目标方法
* @param args:目标方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在该方法中可写增强的功能
System.out.println("增强了....");
Object result = method.invoke(target, args);
return result;
}
}
import com.kuang.demo3.ProxyInvocationHandler;
import com.kuang.seivice.UserService;
import com.kuang.seivice.UserServiceImpl;
public class MyTest {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
ProxyInvocationHandler pih = new ProxyInvocationHandler();\
//设置要代理的对象
pih.setTarget(userService);
//动态生成代理类
UserService proxy = (UserService) pih.getProxy();
proxy.delect();
}
}
对于偏底层的对象还不太懂可以看下这个,就是怎么调用的invoke问题
图出处
https://blog.csdn.net/ShewMi/article/details/78108705?utm_source=app&app_version=4.5.2