Java 动态代理
基于接口的动态代理,基于类的动态代理。
- 1、基于接口 =》JDK动态代理【使用】
- 2、基于类:cglib
- 3、java字节码实现:javasist
需要了解两个类:
- Proxy:代理
- InvocationHandler:调用处理程序
InvocationHandler【调用处理器】
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args);
}
当我们调用代理类对象的方法时,这个“调用”会转送到invoke方法中,代理类对象作为proxy参数传入,参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。
这样一来,我们对代理类中的所有方法的调用都会变为对invoke的调用,这样我们可以在invoke方法中添加统一的处理逻辑。
(也可以根据method参数对不同的代理类方法做不同的处理)
接口
public interface Rent {
void rent();
}
实现类
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东要出租房子");
}
}
代理类
@Data
@Slf4j
public class ProxyInvocationHandler implements InvocationHandler {
public ProxyInvocationHandler(Object target) {
this.target = target;
}
//被代理的接口
private Object target;
//生成得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果
//当我们调用代理类对象的方法时,这个“调用”会转送到invoke方法中,代理类对象作为proxy参数传入
//参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//动态代理的本质,就是使用反射机制实现
log.info("代理类调用之前");
Object res = method.invoke(target, args);
log.info("代理类调用之后");
return res;
}
}
测试
public class Test {
public static void main(String[] args) {
//代理角色:未创建
//通过调用程序处理角色来处理我们要调用的接口对象
ProxyInvocationHandler handler = new ProxyInvocationHandler(new Host());
//这里的proxy就是动态生成的,并没有写(面向接口编程)
Rent proxy = (Rent) handler.getProxy();
proxy.rent();
}
}